【问题标题】:Using factories to create multiple objects when using Dependency Injection使用依赖注入时使用工厂创建多个对象
【发布时间】:2011-09-10 17:39:18
【问题描述】:

我试图弄清楚在使用依赖注入时如何创建多个对象。据我了解,标准方法是注入一个工厂,然后用于创建对象。我挣扎的部分是工厂如何创建对象。到目前为止,我看到了两种可能的解决方案:

Factory 只是使用 new() 来创建对象。

  • 难道 DI 不应该让我摆脱对非值对象使用 new 的束缚吗?
  • 如果要创建的对象具有可由 IoC 解决的依赖关系,会发生什么情况?

使用容器作为服务定位器

  • 以引入反模式为代价解决了仅更新对象的问题,或者如果工厂内限制使用 serviclocater,则它不再是反模式?

感觉就像我可以在一个糟糕的解决方案和一个糟糕的解决方案之间徘徊。是我遗漏了什么还是我理解错了什么?

编辑 目前我根本没有使用 Ioc,而是在考虑 Ninject。尽管 Autofac DelegateFactories 听起来很有希望。

【问题讨论】:

  • 你的工厂可以从容器中解析依赖。您没有指定容器。但是,我可以告诉你 Autofac 对这种情况有明确的支持。见code.google.com/p/autofac/wiki/DelegateFactories
  • 你用的是什么容器?
  • 我没有使用 Ninject 的经验,因此无法对此发表评论。 Autofac 是一个非常好的容器。

标签: dependency-injection inversion-of-control ioc-container


【解决方案1】:

虽然您的工厂接口将在应用程序级别定义,但您通常会在您的 DI 配置附近定义该工厂类的实现,因此作为您的composition root 的一部分。虽然直接从您的代码调用容器是Service Locator anti-pattern 的实现,但在组合根中定义的任何代码都只是mechanics,因此不是服务定位器。只要更新对象或调用容器是在组合根内部(或非常接近)完成的,这不是问题,因为应用程序仍然可以从任何定位器/容器中清除。

换句话说:使用工厂方法。您是否需要直接在工厂内部 new up 对象或使用容器,取决于对象。最好让容器创建对象,尤其是当它们自己获得依赖项时,但并非所有对象都可以由容器创建。在这种情况下,您需要恢复到 new 操作。当代码是组合根的一部分而不是应用程序的一部分时,两者都很好。工厂本身可以拥有自己的依赖项。这应该不是问题。您可以让容器连接工厂实例。

【讨论】:

  • DI容器可以为您建厂。通过这种方式,您不必创建使用容器的代码。来自温莎的示例:docs.castleproject.org/…
【解决方案2】:

对于初学者,我不认为在工厂中使用容器作为服务定位器是一种反模式。在真正的情况下,它是完全合适的。想一想,容器感知工厂实际上是容器扩展,而那些似乎被排除在服务定位器抨击之外。即使是最的 IoC 框架,如 AutoFac 或 Ninject 也具有广泛的扩展功能。这种模式最典型的用例是根据使用服务的位置解析为不同的实现。

关于使用new 在工厂内部创建实例,这也是可以接受的。 IoC/DI 消息在那里有点失真,从不使用new 确实是一个副作用,而不是 DI 的目标。依赖注入的首要任务是将组件的依赖创建外部化。只要工厂本身被注入到组件中,它就可以满足这一要求。在评估此类场景时,您需要问自己的问题是:

  1. 组件本身是否会创建其依赖项? 答:不,工厂有。
  2. 您能否在不修改组件的情况下使组件与不同的依赖项一起工作? 答:是的,通过注入不同的工厂。

我之前说过,IoC 容器只是类固醇的工厂。对于 80% 的用例,它们开箱即用。其他 20% 可能需要对上述两个品种进行调整。当我想创建在运行时需要注册的依赖项和一些输入的组件时,我倾向于使用容器感知工厂,而当我创建对其他服务没有依赖关系的域对象时,我倾向于使用new-ing 工厂,但采取所有它们在运行时的构造参数。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2020-05-04
    • 2012-08-09
    相关资源
    最近更新 更多