使用反射的简单工厂包括在哈希表中存储(注册)各种类型名称及其对应的类类型,然后使用此哈希表在工厂中生成对象。
interface Product
{
void foo();
}
class ProductFactory
{
HashTable m_RegisteredProducts = new HashTable();
public void registerProduct(string productID, Type p) {
m_RegisteredProducts.add(productID, p);
}
public Product createProduct(string productID){
return (Product) new m_RegisteredProducts[productID];
}
}
我不清楚注册新类型的过程何时发生,因为要使用的所有类型都要在运行时加载到哈希表中。对registerProduct()的调用在哪里?
答案 0 :(得分:0)
您的代码没有进行反思,因为它期望实例实现Product
接口,而不是类型。您需要addProduct
来获取Type
实例,检查它是否实现了Product
接口,然后在createProduct
中动态创建它的实例(使用{{1}之类的内容})
这是我很久以前写过类似的文章:http://blixt.org/2009/06/05/getting-types-implementing-class-or-interface
答案 1 :(得分:0)
- 在ProductFactory类中的单个位置为所有不同的类调用registerProduct()没有意义,因为它会破坏使用反射而不是天真的switch / case方法的目的。
醇>
将扩展产品类添加到某个位置(例如插件目录)时,反射非常有用。您有一个字符串列表,用于标识支持的插件,这些插件可以在文本文件中定义(应用程序属性,提供额外的安全层),也可以通过(通过反射)扫描所述插件目录(如果安全性较低,则为有人可以在那里放下被黑的产品。免责声明:我从来没有在C#中做到这一点,但它在Java中运行良好。除了新产品代码并最终修改属性文件之外,不会修改应用程序代码。
- 如果在实现接口的所有类的类定义中调用registerProduct(),则在使用Factory之后创建该类的实例,因此总是会出错。
醇>
我不确定问题中的代码策略是什么(它来自哪里?)。您可能希望在http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern
中阅读更多有关不同反射策略和简单工厂的信息答案 2 :(得分:0)
这取决于。有不同的场景需要不同的策略。 如果所有产品类型都在同一个程序集(或程序集列表)中定义,我经常看到的一种策略你可以这样调用:
var productTypes= from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof(IProduct));
然后为productTypes中的每个元素调用registerProduct()。