使用依赖注入时使用工厂创建多个对象

时间:2011-06-08 09:43:37

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

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

工厂只使用new()来创建对象。

  • DI不应该让我免除使用新的非价值物品吗?
  • 如果要创建的对象具有可以由IoC解决的依赖项,会发生什么?

将Container用作Serviclocator

  • 以引入反模式为代价解决了刚刚更新对象的问题,或者如果服务器的使用在工厂内受到约束,它是否不再是反模式?

感觉我可以在坏的和坏的解决方案之间徘徊。有什么我想念的东西,或者我明白这里有什么不对吗?

编辑目前我根本不使用Ioc,而是考虑Ninject。虽然Autofac DelegateFactories听起来很有希望。

2 个答案:

答案 0 :(得分:3)

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

关于使用new在工厂内创建实例,这也是可以接受的。 IoC / DI消息在那里有点失真,从不使用new 实际上是副作用,而不是DI的目标。依赖注入的第一个必要条件是从组件外部创建依赖项。只要工厂本身被注入组件,工厂就能满足这一要求。在评估此类方案时,您需要问自己的问题是:

  1. 组件本身是否创建了依赖项? A:不,工厂确实。
  2. 您是否可以在不修改组件的情况下使组件使用不同的依赖项? A:是的,注册了另一家工厂。
  3. 之前我说过,IoC容器只是类固醇的工厂。对于80%的使用案例,他们开箱即用。另外20%可能需要调整上述两个品种。当我想创建在运行时需要注册依赖项和一些输入的组件时,我倾向于使用容器感知工厂,当我创建不依赖于其他服务的Domain对象时,new - 工厂,但是在运行时获取所有构造参数。

答案 1 :(得分:2)

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

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