11

我研究过像 Nerddinner 和 ContactManager 这样更简单的应用程序以及像 Kigg 这样更复杂的应用程序。我了解简单的,现在我想了解更复杂的。

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

当我检查更复杂的应用程序(如 Kigg 或 Oxite)时,我看到的一种常见模式是引入(我在这里只是触及表面,但我必须从某个地方开始):

  • IOC DI(以 Kigg 为例)
  • Web 请求生命周期管理器
  • 工作单元

以下是我的问题:

我知道,为了真正拥有松散耦合的应用程序,您必须使用 Unity 之类的东西。但似乎在您将 Unity 引入组合的那一刻,您还必须引入 Web 请求生命周期管理器。这是为什么?为什么像 Nerddinner 这样的示例应用程序没有 Web 请求生命周期管理器?它究竟是做什么的?它是 Unity 特有的吗?

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

谢谢

下面是 Nerddiner 在 DinnersController 级别的 DI 示例:

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

    public DinnersController(IDinnerRepository repository) {
        dinnerRepository = repository;
    }

那么我是否正确地假设由于第一个构造函数控制器“拥有”DinnerRepository,因此它将取决于控制器的生命周期,因为它在那里被声明?

4

2 回答 2

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-exchangeable-informative-trouled-engine.aspx

于 2009-09-26T17:46:59.507 回答
0

我相信,如果不是全部的话,大多数 DI 容器都涉及生命周期的概念。根据所涉及的场景,您可能希望容器始终返回已注册组件的相同实例,而对于另一个组件,您可能希望它始终返回一个新实例。大多数容器还允许您指定在特定上下文中,您希望它返回相同的实例等。

我不太了解 Unity(到目前为止,我使用过 Windsor 和 Autofac),但我怀疑 Web 请求生命周期管理器是生命周期策略的实现,其中容器在单个 Web 的生命周期内提供相同的实例要求。您会在 Windsor 等容器中找到类似的策略。

最后,我想您指的是工作单元。工作单元本质上是一组您希望作为一个原子业务事务成功或失败的操作。如需更正式的描述,请查看 Martin Fowler 的定义。这是一个在领域驱动设计的背景下越来越受欢迎的概念。一个工作单元跟踪您在此类事务中应用的更改,并在适当的时候将这些更改提交到一个 ACID 事务中。例如,在 NHibernate 中,会话支持工作单元的概念,更具体地说,支持更改跟踪,而在 Linq2SQL 中,它是 Context ...

于 2009-09-26T16:37:00.850 回答