ASP.NET MVC UnitOfWork и Бизнес-сервисы / Уровень

Нужна ваша помощь в реализации UnitOfWork для моего бизнес-уровня. Хотите объединить несколько разных вызовов бизнес-сервисов в одну транзакцию. Давайте предположим, что я использую Entity Framework в качестве своего уровня хранилища, и у меня есть дополнительный бизнес-уровень для проверки и других бизнес-правил. В этом примере просто очень, очень просто.

public class MyDbContext
{
    public DbSet<User> Users;
    public DbSet<Contract> Contracts;
}

public class UserService
{
    public UserService(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public void AddUser(User user)
    {
        _dbContext.Users.Add(user);
        _dbContext.SaveChanges();
    }
}

public class ContractService
{
    public ContractService(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public void AddContract(Contract contract)
    {
        _dbContext.Contracts.Add(contract);
        _dbContext.SaveChanges();
    }
}

В моем контроллере:

userService.AddUser(user);
contractService.AddContract(contract);

... Добавленные пользовательские вызовы уже сохраняют изменения, но я хочу сохранить изменения после добавления контракта. Так я могу сделать следующее? Или это как-то плохой дизайн?!

Создайте класс UnitOfWork:

public class UnitOfWork
{
    public UnitOfWork(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public MyDbContext DbContext => _dbContext;

    public void SaveChanges()
    {
        _dbContext.SaveChanges();
    }
}

Измените мои услуги на:

public class UserService
{
    public UserService(UnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public void AddUser(User user)
    {
        _unitOfWork.DbContext.Users.Add(user);
    }
}

public class ContractService
{
    public ContractService(UnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public void AddContract(Contract contract)
    {
        _unitOfWork.DbContext.Contracts.Add(contract);
    }
}

И тогда в моем контроллере я делаю:

userService.AddUser(user);
contractService.AddContract(contract);
unitOfWork.SaveChanges();

Это правильный подход?! Очень нужна ваша помощь и мысли по этому поводу...

Спасибо!!!!

1 ответ

Ваш "UnitOfWork" должен содержать методы, отражающие ваши варианты использования. Таким образом, у меня был бы такой метод, как "CreateContract", который фактически добавляет "user" и "contract", фиксирует транзакцию и просто вызывает этот метод из контроллера.

public void CreateContract(User user,Contract contract)
{
    this.dbContext.Users.Add(user);
    this.dbContext.Contracts.Add(contract);  

    this.dbContext.SaveChanges();
}

Таким образом, вы можете инкапсулировать любой транзакционный код в этом методе. Например, если добавление пользователя и контракта - это не просто вызовы EF, а вызовы различных служб, вы можете использовать распределенную транзакцию или другой код для отката транзакции.

Другие вопросы по тегам