我有一个工厂来制造汽车...它是一个基本工厂,它接受汽车的名称,查找实现1. feeds ( id, user_id, type, object_id)
2. badge ( id, 'badge_name', 'slug' )
3. Post (id, 'post_name', 'post_type')
的所有类,根据汽车名称选择正确的类型,并使用来初始化汽车反思。
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
的正确方法是什么?
一种解决方案是注入工厂,但是 Factory Pattern是IoC本身的一种形式,注入工厂感觉很奇怪。根据{{3}}:
与IoC一起使用工厂没有多大意义,因为 IoC容器在某种意义上是“通用抽象工厂”。
换句话说,根据我的经验,任何时候我想添加一个 我最终以更简单的基于IoC的解决方案作为工厂,这就是为什么我 敢说“ IoC杀死工厂之星”
上面的内容对我来说很有意义,尽管我还没有想到用DI代替Factory的解决方案。
所以我的问题是(对于那些使用工厂模式的人)我应该如何初始化它?
为避免问题过长,我在此问题中使用了一个简化的CarFactory
示例。我已经发布了完整的示例Nikola Malovic。
答案 0 :(得分:1)
最好将依赖项(构造函数,属性,方法)注入您的类型中。最好避免使用new-operator创建依赖关系。
要使其变得更好,您应该为您CarFactory
(ICarFactory
)定义一个接口,并根据该类型更改服务。
在测试中,您可以模拟ICarFactory
并为测试用例提供特殊的实现。
答案 1 :(得分:1)
我认为比较依赖注入容器和工厂是错误的。
是的,这两种责任都是创建某种类型的实例。
但是DI容器负责根据DI配置实例化实例及其所有依赖项。通常,DI容器在应用程序的入口点(main
方法或Web应用程序中的request
)实例化对象。
Factory将根据您的应用程序的某些业务逻辑或某些只能在运行时访问的值创建该类型的实例。
Factory与其他类一样是普通类,可以将其作为依赖项注入。
在您的特定情况下,您仅在运行时知道汽车的名称,因此您将需要一些类,其职责是将名称“转换”为汽车的实例。
答案 2 :(得分:1)
像往常一样,对于此类问题,答案是 It Depends™。这取决于您要解决的问题。尽管此问题同时带有依赖注入和控制反转(在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...
}