我正在尝试弄清楚如何在使用依赖注入时创建多个对象。据我所知,标准方法是注入一个工厂,然后用它来创建对象。我努力的部分是工厂如何创建对象。到目前为止,我看到了两种可能的解决方案:
工厂只使用new()来创建对象。
将Container用作Serviclocator
感觉我可以在坏的和坏的解决方案之间徘徊。有什么我想念的东西,或者我明白这里有什么不对吗?
编辑目前我根本不使用Ioc,而是考虑Ninject。虽然Autofac DelegateFactories听起来很有希望。
答案 0 :(得分:3)
对于初学者,我不考虑在工厂中使用容器作为服务定位器的反模式。在真实情况下,这是完全合适的。考虑一下,容器感知工厂实际上是容器扩展,这些似乎被排除在服务定位器的抨击之外。即使是大多数纯 IoC框架,如AutoFac或Ninject,也具有广泛的扩展功能。此模式的最典型用例是根据服务的使用位置解析不同的实现。
关于使用new
在工厂内创建实例,这也是可以接受的。 IoC / DI消息在那里有点失真,从不使用new
实际上是副作用,而不是DI的目标。依赖注入的第一个必要条件是从组件外部创建依赖项。只要工厂本身被注入组件,工厂就能满足这一要求。在评估此类方案时,您需要问自己的问题是:
之前我说过,IoC容器只是类固醇的工厂。对于80%的使用案例,他们开箱即用。另外20%可能需要调整上述两个品种。当我想创建在运行时需要注册依赖项和一些输入的组件时,我倾向于使用容器感知工厂,当我创建不依赖于其他服务的Domain对象时,new
- 工厂,但是在运行时获取所有构造参数。
答案 1 :(得分:2)
虽然您的工厂界面将在应用程序级别定义,但您通常会将该工厂类的实现定义为接近DI配置,因此将其作为composition root的一部分。尽管直接从代码中调用容器是Service Locator anti-pattern的实现,但是在组合根目录中定义的任何代码都只是mechanics,因此不是服务定位器。只要在组合根内部(或非常接近)完成新对象或调用容器,这不是问题,因为应用程序仍然可以从任何定位器/容器中清除。
换句话说:使用工厂方法。是否需要在工厂内直接new
对象或使用容器取决于对象。让容器创建对象是可取的,特别是当它们依赖于它们时,但并非所有对象都可以由容器创建。在这种情况下,您需要恢复new
操作。当代码是组合根的一部分而不是应用程序的一部分时,两者都很好。工厂本身可以有自己的依赖。这应该不是问题。您可以让容器连接工厂实例。