Asp.net mvc ASP.NETMVC:使用多个存储库&;统一注射

Asp.net mvc ASP.NETMVC:使用多个存储库&;统一注射,asp.net-mvc,dependency-injection,unity-container,Asp.net Mvc,Dependency Injection,Unity Container,我正在使用asp.NETMVC5项目。假设我正在显示客户数据,其中显示了客户详细信息和客户喜爱的产品 因此,我从客户存储库、国家存储库和收藏夹存储库获取数据 很多时候,人们都在unity DI写关于注入存储库的文章。当我使用单个存储库时,这个概念是有意义的,但是当我必须从多个存储库获取数据时,我如何通过unity di将多个存储库注入mvc控制器中 请参阅unity DI注入存储库的小代码 public class FooController : Controller { re

我正在使用asp.NETMVC5项目。假设我正在显示客户数据,其中显示了客户详细信息和客户喜爱的产品

因此,我从客户存储库、国家存储库和收藏夹存储库获取数据

很多时候,人们都在unity DI写关于注入存储库的文章。当我使用单个存储库时,这个概念是有意义的,但是当我必须从多个存储库获取数据时,我如何通过unity di将多个存储库注入mvc控制器中

请参阅unity DI注入存储库的小代码

public class FooController : Controller  
{  
     readonly IFooRepository _repository;  

     // Inject here  
     public ProductController(IFooRepository repository)  
     {  
           _repository = repository;   
     }  

     // Use it here  
     public ActionResult Bar()  
     {  
          var bar = _repository.DoSomething();  
     }  
}  
以上代码参考

现在告诉我如何重构代码,或者我应该遵循什么方法,这样我就可以使用多个存储库,也可以通过Unity DI进行注入


请给我最好的指导。谢谢

只需将所需的任何依赖项添加到控制器的构造函数中即可

public class FooController : Controller  
{  
    readonly IFooRepository _repository;  
    readonly IOtherRepository _otherRepository;  

    public ProductController(IFooRepository repository, IOtherRepository otherRepository)  
    {  
        _repository = repository;   
        _otherRepository = otherRepository;
    }  
请注意,虽然L-Four通常是一种很好的方法,但当您稍后对加载的实体进行一些修改并希望保存它们时,您可能会遇到困难,因为您的存储库中可能会有单独的
DBContext
实例。但这取决于您的存储库、DI实现和配置

例如:

// Assume you want to create a new User with associated Account

var user = _usersRepository.AddUser(new User(....));
var account = _accountRepository.AddAccount(new Account{ ... User = user });

// Now you want to save them both in one transaction... how?
_usersRepository.Commit();
_accountRepository.Commit(); // What if this fails? you have an orphaned user?
为了解决这个问题,我建议实现所谓的工作单元模式。也有一些关于和

可能会让你以后头疼

您的更新代码将是:

public class FooController : Controller  
{  
     readonly IUsersAndAccountUnitOfWork _uow;  

     // Inject here  
     public ProductController(IUsersAndAccountUnitOfWork uow)  
     {  
           _uow = uow;
     }  

     // Use it here  
     public ActionResult Bar()  
     {  
           var user = _uow.Users.AddUser(new User(....));
           var account = _uow.Accounts.AddAccount(new Account{ ... User = user });

           _uow.Commit();
     }  
} 

您可以简单地注册db上下文,使其只存在一个实例,并且只存在于特定(web)请求的范围内。@L-Four Yes!但是最好有一个
Commit
方法。如果它是在存储库级别,我希望它实际上只应用于该存储库,例如,
userRepository.Commit()
应该只将我的更改提交给用户,我不希望它也提交
myOtherRepository
@thmshd中的更改。您是否可以发布一个完整的小示例代码来显示您的代码流?您是否使用任何DI在IRepository和存储库之间映射以自动传递到controller?我不会在存储库中公开提交。上下文是独立于存储库创建和销毁的,并作为一个依赖项传递给存储库的。@L-Four我也不会在存储库中公开提交,我不明白您如何尝试一次提交跨多个存储库完成的多个更改。您的
Commit
方法位于何处,谁负责在DbContext上执行
Commit
?当然,您不希望每个
AddXYZ(…)
方法都提交,您需要控制它,因为您可能需要新的实体ID进行进一步处理。这就是工作单元模式发挥作用的地方。