我想做什么:使用上述名称的字符串参数调用factory.Create方法. create方法查找具有此名称的生成器并返回所述生成器的新实例.
我认为这样做的好处是:我只需添加新的生成器类而无需编辑工厂.
题:
>这是处理这个问题的好方法吗?
>我怎样才能找到所有发电机?反映接口的每个实现/命名空间的每个成员(生成器的接口是唯一的)?
>这种工厂的工作方式是正确的,还是这种模式不同?
最后我会像这样称呼工厂(简化):
//Caller public DataModel GetData2() { var generator = new DataFactory().Create("Gen.2"); return generator.GetData(); } //Factory public class DataFactory { public AbstractDataGenerator Create(string type) { //Here the magic happens to find all implementations of IDataGenerator var allGenerators = GetImplementations(); var generator = allGenerators.FirstOrDefault(f => f.name == type); if (generator != null) return (AbstractDataGenerator)Activator.CreateInstance(generator); else return null; } } //Interface public abstract class AbstractDataGenerator { public static string name; public abstract DataModel GetData(); } //Data-Generators public class DataGen1 : AbstractDataGenerator { public static string name = "Gen.1"; public DataModel GetData() { return new DataModel("1"); } } public class DataGen2 : AbstractDataGenerator { public static string name = "Gen.2"; public DataModel GetData() { return new DataModel("2"); } }
工厂中的神奇GetImplementations()是应该通过Reflection完成还是以某种方式不同?我应该采用完全不同的方法吗?
由于答案是指IoC和DI:这个项目已经使用了NInject,所以它可以使用.
从接口切换到抽象类.
解决方法
Is this a good way to handle this problem?
有一个工厂来获得你需要的逻辑类的实例 – 我相信这是一个好方法.这是我自己经常使用的一种模式.关于你获得密钥的方式 – 我宁愿不把它作为静态成员(不管接口不能有静态成员),而只是作为属性并向IDataGenerator添加基类.该基类将有一个将获得名称的构造函数 – 这样你创建的每个新DataGenerator都必须设置它,你不会忘记.
关于将名称作为字符串 – 我个人更喜欢让它“强类型”.我的意思是,如果我通过Gen. 2而不是Gen.2与字符串我将只在运行时发现此问题.可能的其他方式(如果你想,因为一个简单的字符串也很好 – 一个品味问题):
>用枚举替换字符串
>为所有值创建一个带有静态只读字符串的静态类 – 然后在代码中使用这些值.你得到了intellisense的好处并且没有得到字符串错误但比enum更好 – 你仍然可以传递不在“列表”中的字符串,因此你可以添加新的作为附加组件.
>拥有一个RequestGenerator对象,每个Generator都是IDataGenerator< TGeneratorRequest>.这可能是一种矫枉过正,但是如果您还需要额外的信息来创建不同的DataGenerator,那么请考虑它.
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
是的,反思可能是一个很好的方法.但是,我建议您阅读依赖注入和IoC容器,例如Castle Windsor.有些东西已经为你实现了,所以为什么要重新发明轮子:)
在我看来,DI是改变生活的概念
Is it correct to call this way of working a factory,or is this some different pattern?
邑.这是一个Factory
Should the magic GetImplementations() in the factory be done via Reflection or somehow different?
查看问题2的答案