代码之家  ›  专栏  ›  技术社区  ›  SM Farhad Ali

在控制器中实现依赖注入以创建松散耦合系统

  •  1
  • SM Farhad Ali  · 技术社区  · 13 年前

    我有一个HomeController和一个类型类的Referrence。如果我创建该类的新对象,它对我来说很好。但我不想在Controller中创建新对象,相反,我想通过HomwController的构造函数传递该类的引用。这是我的代码。我需要在这里实现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());
        }
    

    有什么帮助吗?

    2 回复  |  直到 13 年前
        1
  •  2
  •   darkey    13 年前

    首先,如果你想使用依赖注入,你必须通过第三方依赖注入容器——例如,NInject或Unity以及其他许多容器(或者,如果你正在寻找一些挑战,可以构建自己的容器)。

    其次,您的HomeController应该采用一个抽象的工作单元类型(接口或抽象类)作为参数。实际上,您在HomeController构造函数中使用了一个具体类型,这不是依赖注入世界中的工作方式(当使用“构造函数注入”时,依赖容器负责根据容器配置为抽象提供具体实现)。

    你的第三个 UnitOfWork<Student> 没有多大意义。A. Repository<Student> 这在一定程度上是有道理的,但工作单元不是针对单个“类型”,而是针对不同数据集的“集合”(一个工作单元可能针对存储库的集合)。这里有意义的是指定一个参数 IUnitOfWork unitOfWork 在HomeController构造函数中,并将depency容器配置为传入混凝土 UnitOfWork 您可以在其上获得 存储库<学生> 在操作方法中对其进行操作(可能还会对从UnitOfWork对象访问的其他存储库进行操作),然后通过调用 工作单位 对象

    如果您正在处理UnitOfWork和Repository模式(以及数据由DB支持),您应该在NInject附近使用ASP.NET MVC3进行一些搜索,并查看EntityFramework。

    编辑

    针对您的评论,处理 (IUnitOfWork<Student> IUnitOfWork<Course> )。

    正如我之前所说,这没有多大意义:

    UnitOfWork可以被粗略地视为存储库的“容器”,允许访问这些存储库并协调这些存储库上的操作(如提交所有更改)。你应该有一个抽象的非泛型类型 IUnitOfWork ,提供对通用存储库的访问,例如 IRepository<Student> IRepository<Course> ,还包含一个Commit方法,该方法将提交到DB(或文件、内存或任何工作单元/存储库实现旨在持久化数据的内容)。

    这种方式而不是注入 I存储<学生> 和/或 I存储<课程> 在您的控制器构造函数中(或者,如果您的控制器需要在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/

        2
  •  1
  •   Steen Tøttrup    13 年前

    你说的是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类的构造函数中的任何参数也绑定在内核中。

    推荐文章