我有一家制造汽车的工厂。它是一个基本的工厂,它接受汽车的名称,查找所有实现ICar
的类,根据汽车名称选择正确的类型,并使用反射初始化汽车。
public class CarFactory
{
Dictionary<string, Type> cars;
public ICar CreateInstance(string carName)
{
// choose type of class from all classes that implement ICar
Type t = GetTypeToCreate(carName);
return Activator.CreateInstance(t) as ICar;
}
// some more code...
}
现在,我有一个使用CarFactory
的服务。在我的服务中初始化CarFactory
的正确方法是什么?
一种解决方案是注入工厂,但是工厂模式是IoC本身的一种形式,注入工厂感觉很奇怪。根据Nikola Malovic的说法
同时使用工厂和IoC的
没有多大意义,因为IoC容器在某种意义上是“通用抽象工厂”。
换句话说,根据我的经验,每当我想要增加一家工厂时,我最终都会使用更简单的基于IoC的解决方案,这就是为什么我敢说“IoC杀死工厂之星”的原因。
上面的内容对我来说完全有意义,尽管我还没有想出一个解决方案来用DI取代我的Factory。
所以我的问题是(对于那些使用工厂模式的人)我应该如何初始化它?
为了避免问题太长,我在这个问题中使用了一个简化的CarFactory
示例。我已经发布了完整的示例here。
发布于 2018-10-31 22:52:15
像往常一样,对于这类问题,答案是It依赖于。这取决于你试图解决的问题。虽然这个问题同时带有依赖注入和控制反转(在某种程度上是the same idea)的标签,但这些本身都不是目标,而只是实现适当目标的手段。
通常,目标是行为的解耦。这就引出了第一个问题,然后:
为什么CreateInstance
会返回ICar
实例?
这里我假设ICar
是一个接口。ICar
是多态的吗?您是否有该接口的多个实现?
在我看来,一个名为car的对象听起来像一个实体和那些should usually not be injected,因为它们通常表示数据,而不是行为。
不过,为了便于讨论,我们假设ICar
确实是多态的。
如下所示,CarFactory
看起来是确定性的。不过,很难说,因为并没有显示整个实现。但是,如果它是referentially transparent,那么为什么还要初始化它呢?
它不能只是一个静态函数吗?
public static class CarFactory
{
public static ICar CreateInstance(string carName)
{
// choose type of class from all classes that implement ICar
Type t = GetTypeToCreate(carName);
return Activator.CreateInstance(t) as ICar;
}
// some more code...
}
发布于 2018-10-29 15:11:00
最好将依赖项(构造函数、属性、方法)注入到类型中。最好避免使用new-operator创建依赖项。
为了让它更好,您应该为您的CarFactory
(ICarFactory
)定义一个接口,并将您的服务更改为依赖于该类型。
在测试中,您可以模拟ICarFactory
并为您的测试用例提供特殊的实现。
发布于 2018-10-30 19:07:17
我认为比较依赖注入容器和工厂是错误的。
是的,这两个责任都是创建某种类型的实例。
但DI容器负责基于DI配置实例化实例及其所有依赖项。通常DI容器在应用程序的入口点实例化对象( web应用程序中的main
方法或request
)。
其中,工厂将基于应用程序的某些业务逻辑或只能在运行时访问的某些值来创建该类型的实例。
Factory和其他类一样是普通类,可以将它作为依赖项注入。
在您的特定情况下,您只在运行时知道汽车的名称,因此您将需要一些类,该类的职责是将名称“转换”为汽车的实例。
https://stackoverflow.com/questions/53040265
复制相似问题