Dependency injection 使用依赖项注入时使用工厂创建多个对象
我试图弄清楚在使用依赖项注入时如何创建多个对象。据我所知,标准方法是注入一个工厂,然后用于创建对象。我要讨论的部分是工厂如何创建对象。到目前为止,我看到了两种可能的解决方案: 工厂只使用new()创建对象。Dependency injection 使用依赖项注入时使用工厂创建多个对象,dependency-injection,inversion-of-control,ioc-container,Dependency Injection,Inversion Of Control,Ioc Container,我试图弄清楚在使用依赖项注入时如何创建多个对象。据我所知,标准方法是注入一个工厂,然后用于创建对象。我要讨论的部分是工厂如何创建对象。到目前为止,我看到了两种可能的解决方案: 工厂只使用new()创建对象。 DI不应该让我不用为非值对象使用new吗 如果要创建的对象具有可由IoC解析的依赖项,会发生什么情况 将容器用作服务克隆器 解决了以引入反模式为代价仅更新对象的问题,或者,如果工厂内限制了对服务的使用,那么它是否不再是反模式 我觉得我可以在一个坏的解决方案和一个坏的解决方案之间保持沉
- DI不应该让我不用为非值对象使用new吗
- 如果要创建的对象具有可由IoC解析的依赖项,会发生什么情况
- 解决了以引入反模式为代价仅更新对象的问题,或者,如果工厂内限制了对服务的使用,那么它是否不再是反模式
编辑目前我根本没有使用国际奥委会,而是在考虑Ninject。尽管Autofac DelegateFactorys听起来很有前途。尽管工厂的接口将在应用程序级别定义,但您通常会在DI配置附近定义该工厂类的实现,从而将其作为应用程序的一部分。尽管直接从代码调用容器是的一个实现,但在Composition根目录中定义的任何代码都只是服务定位器,因此不是服务定位器。只要在组合根内部(或非常靠近)完成对象的更新或对容器的调用,这就不是问题,因为应用程序仍然可以从任何定位器/容器中清除
换句话说:使用工厂方法。是否需要直接在工厂内
新建对象或使用容器,取决于对象。让容器创建对象是可取的,特别是当它们自己具有依赖关系时,但并非所有对象都可以由容器创建。在这种情况下,您需要恢复到new
操作。当代码是合成根的一部分而不是应用程序的一部分时,这两种方法都可以。工厂本身可以有自己的依赖项。这应该不是问题。您可以让容器将工厂实例引线。 对于初学者,我不认为在工厂中使用容器作为服务定位器是反模式。有些情况是完全适当的。仔细想想,容器感知工厂实际上是容器扩展,这些工厂似乎被排除在服务定位器攻击之外。即使是最纯粹的IoC框架,如AutoFac或Ninject,也具有广泛的扩展能力。此模式最典型的用例是根据服务的使用位置解析为不同的实现
关于使用new
在工厂内创建实例,这也是可以接受的。IoC/DI的信息有点失真,从不使用new
实际上是一种副作用,而不是DI的目标。依赖项注入的首要任务是从组件外部化依赖项的创建。工厂满足这一要求,只要它自己被注入到组件中。在评估此类场景时,您需要问自己以下问题:
组件本身是否创建其依赖项A:不,工厂有
您能否在不修改组件的情况下使其与不同的依赖项一起工作A:是,通过注入不同的工厂
我以前说过,IoC容器只是类固醇工厂。对于80%的用例,它们是开箱即用的。另外20%可能需要对上述两个品种进行调整。当我想要创建在运行时既需要注册依赖项又需要一些输入的组件时,我倾向于使用容器感知工厂;当我创建对其他服务没有依赖项的域对象时,我倾向于使用new
-ing工厂,但是在运行时获取它们的所有构造参数。您的工厂可以从容器中解析依赖项。您没有指定容器。但是,我可以告诉您,Autofac明确支持此场景。看到你用的是什么容器了吗?我没有Ninject的经验,所以无法对此发表评论。Autofac是一个非常好的容器。DI容器可以为您建造工厂。这样,您就不必创建使用容器的代码。温莎的例子: