首先,如果你想使用依赖注入,你必须通过第三方依赖注入容器——例如 NInject 或 Unity 等等(或者如果你正在寻找一些挑战,也可以构建自己的)。
其次,您的 HomeController 应该将工作类型的抽象单元(接口或抽象类)作为参数。您实际上在 HomeController 构造函数中使用了具体类型,这不是在依赖注入世界中的工作方式(当使用“构造函数注入”时,您的依赖容器负责根据容器配置为抽象提供具体实现)。
第三,你UnitOfWork<Student>
的意义不大。ARepository<Student>
会有些道理,但工作单元不是在单一“类型”上工作,而是在不同数据集的“集合”上工作(一个工作单元可能在一个存储库集合上工作)。这里有意义的是IUnitOfWork unitOfWork
在您的 HomeController 构造函数中指定一个参数,并配置您的依赖容器以传入一个具体UnitOfWork
对象,您可以Repository<Student>
在您的操作方法中对它进行 do 操作(以及可能在从 UnitOfWork 访问的其他存储库上)对象),然后通过调用UnitOfWork
对象上的关联方法来提交所有修改。
如果您正在处理 UnitOfWork 和 Repository 模式(并且如果数据由数据库支持),您应该围绕 NInject 与 ASP.NET MVC3 一起使用进行一些搜索,并查看 EntityFramework。
编辑
回应您处理(IUnitOfWork<Student>
和IUnitOfWork<Course>
) 的评论。
正如我之前所说,这没有多大意义:
UnitOfWork 可以粗略地视为存储库的“容器”,可以访问这些存储库并在这些存储库上协调操作(如提交所有更改)。您应该拥有一个抽象的非泛型类型IUnitOfWork
,提供对诸如IRepository<Student>
or之类的泛型存储库的访问IRepository<Course>
,并且还包含一个 Commit 方法,该方法将提交到 DB(或文件、内存或任何 unitofwork/repository 实现的目标是持久化数据)。
这样,您无需在控制器构造函数中注入IRepository<Student>
和/或IRepository<Course>
(或者如果您的控制器需要在 10 个不同的存储库上工作,那么,传递 10 个参数:S),您只需接受抽象类型 IUnitOfWork 的单个参数(具体实例是由 DI 容器注入),然后任何操作方法都可以通过从 UnitOfWork 获取它们来处理任何存储库集,并且一旦完成所有更改,它就可以在 unitOfWork 上调用 Commit 来处理所有已在存储库中进行的修改。
这就是理论和总体思路。
现在更具体地说是关于 ASP.NET MVC 中的 DI,“管道”DI 容器的更常见方法(还有其他方法)是创建一个继承自IDependencyResolver
使用 DI 容器来解析类型的类,并在Application_Start
调用中DependencyResolver.SetResolver
调用这个类的实例。这样,当 ASP.NET MVC 被要求创建一个控制器(最终用户请求)时,它会通过这个依赖解析器来请求一个控制器的实例,这个依赖解析器会转向 DI 容器来创建一个实例通过照顾所有需要的注射来控制控制器。您应该查看特定 DI 容器的网站/论坛,因为它们都显示了使用 ASP.NET MVC 检测它的方法。
这只是一个非常高的概述,有很多棘手的细节,但这是粗略的想法。
编辑2
刚刚在我的博客上发布了一篇文章(我的第一篇),解释了如何在 ASP.NET MVC 项目中正确使用 Repository 和 UnitOfWork 模式。
http://codefizzle.wordpress.com/2012/07/26/correct-use-of-repository-and-unit-of-work-patterns-in-asp-net-mvc/