2016-08-31 12 views
0

необходимо, чтобы вы помогли реализовать UnitOfWork для моего бизнес-уровня. Хотите объединить несколько разных вызовов бизнес-сервисов в одну транзакцию. Предположим, что я использую Entity Framework в качестве уровня моего репозитория, и у меня есть дополнительный бизнес-уровень для проверки и других бизнес-правил. В этом примере это очень просто.ASP.NET MVC UnitOfWork and Business Services/Layer

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(); 

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

Спасибо !!!!

ответ

0

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

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

    this.dbContext.SaveChanges(); 
} 

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

+0

Хммм, но у меня есть сотни таких цепочек вызовов службы, которые должны выполняться как одна транзакция. Я не могу добавить все эти методы в один класс UnitOfWork ... Okey я мог бы создать класс UnitOfWork для разных областей, но в конце моего веб-приложения почти каждая транзакция представляет собой одно действие webrequest/controller ... Вот почему я хочу для вызова Commit в конце действия контроллера, когда все служебные вызовы были успешными ... – Simon