DI / IoC容器与工厂:我在哪里配置应用程序,为什么?


9

我试图弄清楚何时使用DIC / IoC注册表来配置我的软件以及何时使用工厂,以及这两种方法背后的原因。


我正在使用StructureMap作为我的DI容器(DIC),使用注册表很容易配置它。在DIC中,从某种意义上说,实际上所有注册的对象都是静态的,一旦配置了DIC并且在DIC中将它们配置为单例,就不需要在运行时更改/交换任何实现/实例。但是,由于我的软件(SW)将在不同的设备上运行,因此我确实需要根据运行我的SW的设备选择特定于设备的注册表,以便相应地配置硬件。

由于某些对象的构造需要读取配置文件,因此我正在使用工厂将这些实例返回给DIC,以便将配置的读取与对象的创建分开。我在DIC中为相应的插件类型注册了工厂吸气剂。

现在说我有一个插件类型IMotor与具体类型Motor1Motor2,这应该由厂家来处理。现在,有两种方法可以决定如何配置设备:

  1. 我将有关运行SW的设备的信息传递给,MotorFactory并且它返回正确的电动机,Motor1或者Motor2。在这种情况下,决定的逻辑是工厂内部
  2. 我根据运行它,并创建两个工厂的设备配置DIC Motor1FactoryMotor2Factory,其中一个创建Motor1和其他 Motor2。在这种情况下,对于IMotor使用Motor1Factory或的设备特定的注册表,我会有不同的注册表项Motor2Factory

现在我的问题是:这两种方法中哪一种更可取,为什么?在我看来,第一种情况并非一帆风顺,而且令人费解,因为我在整个代码库中扩展了决定实例化哪种类型的逻辑。在第二种情况下,由于我将需要(几乎)每种具体类型的工厂,因此我实际上在代码中增加了工厂的数量。当将抽象工厂添加到组合中时,这让我更加困惑。

再说一遍:什么时候应该使用一种方法?更重要的是:什么是决定走哪条路的好指标?


2
哪种方法更简单?更复杂的方法的好处是否超过了额外复杂性的代价?
罗伯特·哈维

Answers:


2

如果您同时使用这两种方法,那么我会做一些简单的事情:

  • DI / IoC:对于运行时不会更改的每个配置。
  • 工厂:用于在运行时创建对象实例,具体取决于运行时输入参数。工厂实例由DI容器注入。

1

当您具有需要通过层次结构一起变化的相关对象时,将使用抽象工厂。我在这里看不到。

我所看到的是,您想知道工厂应该选择电动机还是DIC是否应该选择生产特定电动机的工厂。

很难精确选择是因为工厂和DIC所做的事情非常相似。不同之处在于工厂专注于特定问题,而DIC则更为笼统。

归结为这个问题:您是否需要专门针对此问题的代码,这些代码将在工厂中使用?还是更通用,例如从文件中读取配置详细信息?

请记住,虽然您可能只在今天Motor1Motor2今天之间进行选择,但明天可能会有一个Motor3。支持Motor3易于添加的设计。


0

我将逻辑“使用哪个马达”分离到一个特殊的工厂中,称为Builder(模式), 并将两个马达的IOC容器用作构建器的实现细节。

作为基本规则:

  • 如果必须创建类/接口的许多动态对象,则需要工厂(或构建器)。(即,您生产的每一辆汽车都必须创建一个新的电动机)
  • 如果您只需要一个类的静态实例,那么ioc / di可以为您完成工作(即,您只需要一个PaymentService的静态实例和一个MotorBuilderService的静态实例)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.