【发布时间】:2011-12-01 17:48:50
【问题描述】:
我正在取得进展,但仍在努力处理多层 MVC 应用程序中的工作单元。查看此处的示例:http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application UoW 包装了所有存储库,并为每个存储库提供了相同 dbcontext 的副本。然后控制器可以使用类似的存储库:
var courses = unitOfWork.CourseRepository.Get(includeProperties: "Department");
现在假设您有一个访问存储库的服务层。您可以对其进行配置,使其依赖于 IUnitOfWork 实现,然后通过 Unity 传入 EfUnitOfWork 实现。然后,当服务完成某些任务时,它可以调用 unitOfWork.context.SaveChanges()。但是这种方法隐藏了服务的真正依赖关系;它需要的存储库。这也意味着测试服务需要您构建完整的 UoW。
所以我在想一定有一种不同的方法,我想知道以下方法之一或我上面提到的(或其他东西!)是否是正确的方法:
- Service 接受相同的存储库参数和一个 IUnitOfWork。存储库与 Unity 提供的 dbContext 副本连接起来。 EfUnitOfWork 也连接到同一个副本。然后,服务可以像以前一样使用存储库,完成后使用 EfUnitOfWork 提交。
- Service 只接收一个 IUnitOfWork,但通过将传入的 IUnitOfWork.dbcontext 的副本传递给它们来设置其所需的存储库
请帮忙!
詹姆斯
【问题讨论】:
-
看看this blog post of mine,它向 IMO 展示了一个优雅的解决方案。
-
DbContext是一个工作单元,DbSet是一个存储库。 I too have blogged about this,尽管我仍然需要再写一两篇文章来完成我的想法。我的解决方案的要点是尽可能重用生成的 EF 代码。最后,您创建了一个IUnitOfWork,即IDisposable,具有SaveChanges方法,并公开IDbSet<TEntity>属性。然后为你的DbContext创建一个部分类,并使其实现IUnitOfWork接口。 -
您可能必须稍微修改 T4 模板才能使部分类/接口的内容正常工作,并公开
IDbSet<TEntity>属性。最后,您的服务层将接受IUnitOfWork,有点像安德斯的回答,但它会在整个过程中使用接口而不是具体类(因此您不会直接公开DbContext)。这个解决方案可以被完全模拟/存根。 -
感谢您的指导,这一切都帮助我了解了各种模式和工具。我认为现在我将坚持使用我在下面记录的解决方案,使用 DbContext 作为 UoW,使用 EF。
-
@Merlyn Morgan-Graham:你的博客不可用。你把它移到其他网站了吗?很好奇阅读它!
标签: asp.net-mvc asp.net-mvc-3 dependency-injection unit-of-work