我有一个HomeController和一个类型类的引用。如果我创建了一个类的新对象,它对我来说很好。但我不想在Controller中创建新对象,而是想通过HomwController的Constructor传递类的引用。这是我的代码。我需要在这里实施DI。
//private readonly UnitOfWork<Student> _unitOfWork = new UnitOfWork<Student>();
private readonly UnitOfWork<Student> _unitOfWork;
//TODO ??
public HomeController(UnitOfWork<Student> unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
return View(_unitOfWork.GenericRepository.GetAll());
}
任何帮助?
答案 0 :(得分:2)
首先,如果你想使用依赖注入,你将不得不通过第三方依赖注入容器 - 例如NInject或Unity等许多其他容器(如果你正在寻找一些挑战,那么建立你自己的容器)。 / p>
其次,您的HomeController应该将抽象的工作单元类型(接口或抽象类)作为参数。实际上,你在HomeController构造函数中使用了一个具体的类型,而不是在依赖注入世界中应该如何工作(当使用“构造函数注入”时,你的依赖容器负责根据容器配置提供抽象的具体实现。 )。
你的UnitOfWork<Student>
第三个没有多大意义。 Repository<Student>
会有所帮助,但是工作单元不是在单个“类型”上工作,而是在不同数据集的“集合”上工作(一个工作单元可能在一组存储库上工作) 。这里有意义的是在HomeController构造函数中指定参数IUnitOfWork unitOfWork
,并配置您的依赖项容器以传递一个具体的UnitOfWork
对象,您可以在该对象上执行Repository<Student>
操作它在您的操作方法中(可能在从UnitOfWork对象访问的其他存储库中),然后通过调用UnitOfWork
对象上的关联方法来提交所有修改。
你应该在NInject中使用ASP.NET MVC3进行一些搜索,如果你正在处理UnitOfWork和Repository模式(如果数据是由数据库支持的话),还应该看一下EntityFramework。
修改强>
对您处理(IUnitOfWork<Student>
和IUnitOfWork<Course>
)的评论作出回应。
正如我之前所说,它没有多大意义:
UnitOfWork可以被视为存储库的“容器”,可以访问这些存储库并协调这些存储库上的操作(如提交所有更改)。您应该使用抽象的非泛型类型IUnitOfWork
,提供对IRepository<Student>
或IRepository<Course>
等通用存储库的访问,并且还包含将提交到DB(或文件,或者内存或任何单元工作/存储库实现的目标是持久化数据。)
这样,而不是在控制器构造函数中注入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进行检测的方法。
这只是一个非常高的概述,有很多棘手的细节,但这是一个重要的想法。
<强> EDIT2 强>
刚刚在我的博客上发表了一篇文章(我的第一篇),解释了如何在ASP.NET MVC项目中正确使用Repository和UnitOfWork模式。
答案 1 :(得分:1)
你在谈论ASP.NET MVC吗?
我和Ninject已经有一段时间了,我很高兴!查看此存储库中的示例应用程序,以了解如何在ASP.NET MVC 3中使用它:
https://github.com/ninject/ninject.web.mvc/tree/master/mvc3
要在回复中稍微扩展一下,这里是我设置Ninject绑定的代码片段
kernel.Bind(typeof(IUnitOfWork<>).To(typeof(UnitOfWork<>));
我的控制员:
public class MyController : Controller {
private readonly IUnitOfWork<Student> uowStudent;
public MyController(IUnitOfWork<Student> uowStudent) {
this.uowStudent = uowStudent;
}
}
然后你需要做的就是确保UnitOfWork类的构造函数中的任何参数也绑定在内核中。