将我的MVC提升到新的水平:DI和工作单元

Tho*_*mas 11 asp.net-mvc ioc-container unity-container

我已经看过像Nerddinner和ContactManager这样的简单应用程序以及像Kigg这样的更复杂的应用程序.我理解更简单的那些,现在我想了解更复杂的那些.

通常,较简单的应用程序在LINQtoSQL或实体框架之上具有存储库类和接口(尽可能松散耦合).从控制器调用存储库以执行必要的数据操作.

我在研究更复杂的应用程序(如Kigg或Oxite)时看到的一个常见模式是引入(我只是在这里搔痒但我必须从某处开始):

  • IOC DI(在Kigg案例Unity中)
  • Web请求终身经理
  • 工作单位

这是我的问题:

我知道为了真正拥有一个松散耦合的应用程序,你必须使用像Unity这样的东西.但是,当你将Unity引入混合时,你也必须引入一个Web Request Lifetime Manager.这是为什么?为什么像Nerddinner这样的示例应用程序没有Web请求终身管理器?它到底是做什么用的?这是Unity特定的事情吗?

我注意到的第二种模式是引入工作单元.同样,同样的问题:为什么Nerddinner或ContactManager不使用工作单位?相反,这些应用程序使用Linq2Sql或Entity Framework之上的存储库类来执行数据操作.没有任何工作单位的迹象.究竟是什么以及为什么要使用它?

谢谢

以下是DinnersController级别的Nerddiner中DI的示例:

    public DinnersController()
        : this(new DinnerRepository()) {
    }

    public DinnersController(IDinnerRepository repository) {
        dinnerRepository = repository;
    }
Run Code Online (Sandbox Code Playgroud)

所以我是正确的假设因为第一个构造函数控制器"拥有"DinnerRepository,因此它将依赖于控制器的生命周期,因为它在那里被声明了?

que*_*en3 3

通过直接使用 Linq-to-SQL,您的控制器拥有对数据上下文的引用。它通常是控制器内部的私有引用,因此是作为其构造的一部分创建的。无需生命周期管理,因为它位于一处。

但是,当您使用 IoC 容器时,您的数据存储库是在控制器外部创建的。由于为您创建对象的 IoC 容器不知道您将如何以及使用创建的对象多长时间,因此引入了生命周期策略。

例如,数据上下文(存储库)通常在 Web 请求开始时创建并在结束时销毁。但是,对于使用外部 Web 服务或某些静态映射器(例如记录器)的组件,无需每次都创建它们。所以你可能想说创建一次(即单一生活方式)。

所有这一切的发生是因为 IoC 容器(如 Unity)被设计为处理多种情况,并且它们不知道您的具体需求。例如,某些应用程序使用“会话”事务,其中 NHibernate(或实体框架可能)可能会在多个页面/Web 请求期间持续。IoC 容器允许您调整对象的生命周期以满足您的需求。但正如所说,这是有代价的 - 由于没有单一的预定义策略,因此您必须自己选择一个。

为什么 NerdDinner 和其他应用程序不使用更先进的技术,只是因为它们旨在演示 MVC 功能,而不是其他一些库的高级用法。我记得一篇文章是为了演示一个 IoC 容器高级功能而写的 - 这篇文章打破了一些已批准的设计模式,例如关注点分离 - 但这并不重要,因为设计模式不是本文的目标。与简单的 MVC 演示应用程序相同 - 他们不希望您(MVC 新手)迷失在 IoC 迷宫中。

我不建议将 Oxite 作为设计参考示例: http ://codebetter.com/blogs/karlseguin/archive/2008/12/15/oxite-oh-dear-lord-why.aspx http:// ayende.com/Blog/archive/2008/12/19/oxite-open-exchangable-informative-troubled-engine.aspx