ASP.NET MVC UnitOfWork和业务服务/层

时间:2016-08-31 09:19:11

标签: c# asp.net asp.net-mvc unit-of-work business-layer

需要您帮助我的业务层实施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 个答案:

答案 0 :(得分:0)

您的“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调用而是调用不同的服务,则可以使用分布式事务或其他代码来回滚事务。