简体   繁体   中英

ASP.NET MVC UnitOfWork and Business Services / Layer

need you help implementing UnitOfWork for my business layer. Want to wrap multiple different business service calls into a single transaction. Let's assume I use Entity Framework as my repository layer and I have an additional business layer for validation and other business rules. In this example just very very simple.

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

In my controller:

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

... The add user calls already save changes but i want to save changes after add contract. So can I do the following?? Or is this somehow bad design?!

Create UnitOfWork class:

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

    public MyDbContext DbContext => _dbContext;

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

Change my services to:

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

And then in my controller I do:

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

Is this a valid approach?! Really need your help and thoughts on this...

Thanks!!!!

Your 'UnitOfWork' should contain methods that reflect your use cases. So I would have a method like 'CreateContract' which actually adds the 'user' and 'contract' and commits the transaction and just call this method from the controller.

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

    this.dbContext.SaveChanges();
}

This way you can encapsulate any transactional code within this method. Ex - if adding a user and contract are not simply EF calls but calls to different services, you can have a distributed transaction or other code to rollback the transaction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM