Dependency injection 依赖项注入的工作单元

Dependency injection 依赖项注入的工作单元,dependency-injection,inversion-of-control,ninject,repository-pattern,unit-of-work,Dependency Injection,Inversion Of Control,Ninject,Repository Pattern,Unit Of Work,我正在ASP.NETMVC4中构建一个相对简单的webapp,使用实体框架与MS SQL Server进行对话。将来扩展应用程序还有很多空间,所以我的目标是创建一种模式,最大限度地提高代码的可重用性和适应性,以节省以后的工作。这个想法是: 工作单元模式,通过仅在每组操作结束时提交更改来保存数据库问题 使用BaseRepository的通用存储库,因为存储库基本相同;奇数异常可以扩展并添加其附加方法 依赖注入将这些存储库绑定到控制器将使用的I存储库,这样我就可以以最小的麻烦切换数据存储方法等(不

我正在ASP.NETMVC4中构建一个相对简单的webapp,使用实体框架与MS SQL Server进行对话。将来扩展应用程序还有很多空间,所以我的目标是创建一种模式,最大限度地提高代码的可重用性和适应性,以节省以后的工作。这个想法是:

  • 工作单元模式,通过仅在每组操作结束时提交更改来保存数据库问题
  • 使用
    BaseRepository
    的通用存储库,因为存储库基本相同;奇数异常可以扩展并添加其附加方法
  • 依赖注入将这些存储库绑定到控制器将使用的
    I存储库
    ,这样我就可以以最小的麻烦切换数据存储方法等(不仅仅是为了最佳实践;这种情况很有可能发生)。我用Ninject来做这个
我以前从未真正尝试过这样的事情,所以我一直在阅读,我想我在什么地方弄糊涂了。到目前为止,我有一个接口
IRepository
,它由
BaseRepository
实现,其中包含一个传递到其构造函数中的
DataContext
实例。此接口具有用于添加、更新、删除和各种类型的Get的方法(按ID、按谓词、按谓词分组、全部)。到目前为止,唯一不适合此界面的存储库是用户存储库,它添加了
用户登录(字符串用户名、字符串密码)
以允许登录(其实现处理所有的salt、hash、检查等)

根据我所读的内容,我现在需要一个包含所有存储库实例的
UnitOfWork
类。此工作单元将公开存储库以及SaveChanges()方法。当我想要操作数据时,我实例化一个工作单元,访问其中的存储库(根据需要实例化),然后保存。如果任何操作失败,数据库中的任何内容都不会更改,因为它最终不会到达单个存储。这一切都很好。我的问题是,我能找到的所有例子似乎都做了两件事之一:

  • 有些人将数据上下文传递到工作单元,从中检索各种存储库。这通过在我的工作单元中使用特定于实体框架的
    DbContext
    (或从中继承的类),否定了DI的意义
  • 有些人调用Get方法来请求存储库,这是服务定位器模式,如果不是反模式的话,这至少是不受欢迎的,我希望在这里避免使用这种模式
我是否需要为我的数据源创建一个接口,并将其注入到工作单元中?我找不到任何足够清晰和/或完整的文档来解释

编辑

我想我已经把它复杂化了;我现在将我的存储库和工作单元合并为一个—我的存储库是完全通用的,所以这只给了我一些通用方法(添加、删除、更新和几种Get)以及一个SaveChanges方法。这给了我一个工人类接口;然后,我可以有一个工厂类来提供它的实例(也可以接口)。如果我也有这个worker实现
IDisposable
,那么我可以在一个作用域块中使用它。现在,我的控制器可以执行以下操作:

using (var worker = DataAccess.BeginTransaction())
{
    Product item = worker.Get<Product>(p => p.ID == prodName);
    //stuff...
    worker.SaveChanges();
}
使用(var worker=DataAccess.BeginTransaction())
{
产品项=worker.Get(p=>p.ID==prodName);
//东西。。。
worker.SaveChanges();
}
如果在
SaveChanges()
之前出现问题,那么当它退出作用域块并释放工作进程时,所有更改都将被丢弃。我可以使用依赖项注入为
DataAccess
字段提供具体的实现,该字段被传递到基本控制器构造函数中。业务逻辑都在控制器中,并与
IQueryable
对象一起工作,因此我可以为任何我喜欢的对象切换
DataAccess
provider对象,只要它实现
IRepository
接口;任何地方都没有特定于实体框架的内容


那么,对这个实现有什么想法吗?这是否在正确的轨道上?

我更喜欢将
UnitOfWork
UnitOfWorkFactory
注入到存储库中,这样我就不必每次添加新的reposiory时都麻烦它了。UnitOfWork的职责就是管理事务


这是我的意思的一个例子。

我很想告诉你。在学术上探讨这个问题没有什么错,但我觉得你所预见的会发生广泛的变化,你可能会发现自己不得不对自己的设计做很多改变。更糟糕的是,你可能会被困其中。我很感激这一点,通常我也会同意,但我知道这可能是必要的。我正在构建使用MSSQL server部署到服务器的版本,但我还有其他人也需要版本,至少其中一人无法访问该版本。没有一个单一的系统适用于所有将要部署到的地方。如果我知道我可以编写一个新的数据访问层实现,并将一些绑定切换到其他地方部署,这将为我以后的工作节省时间。我想学习如何正确地完成这项工作,这是一个很好的机会。我完全不知道你的设置是什么,只是你的描述似乎表明你正在寻求建立一个经得起未来考验的东西(我不太喜欢),因此提到了雅格尼。但有了这个澄清,我想你已经到了一个地步,你可以设计一些通用的东西。“未来证明”是一个危险的术语;未来是模糊和不可预测的。这与其说是未来的证明,不如说是设计阶段1以避免在阶段2中引起更多工作。相关: