我有一个基类的静态工厂方法,使派生类:地图类型名称派生类
public class Fruit
{
...
static Dictionary<string, Type> classes = new Dictionary<string, Type>
{
{"apple", typeof(Apple)}
,{"orange", typeof(Orange)}
}
public static Fruit makeFruit(string typeName) {
if(classes[typeName] == null) throw new Exception("invalid fruit type");
Fruit fruit = Activator.CreateInstance(classes[typeName]) as Fruit;
// do some intializations
return fruit;
}
}
如何添加从果派生的类,让水果类了解它,而无需修改水果类代码本身?其实我只需要通过放入Banana.DLL或添加Banana.cs文件到我的项目中即可添加水果。在像JavaScript等语言我只需添加类水果的静态数组类声明之后:
function Banana()
{
...
}
Fruit.classes['banana'] = Banana;
当然这是不可能在C#中,我试图把代码中的静态构造函数内部,但也不至于工作要么是因为ctor只在类的第一个实例化之前被调用。想到的另一个解决方法是让基类扫描所有程序集中定义的所有类,以找到其所有派生类,并从每个派生类中定义的静态字符串成员中检索typeName,但感觉像是矫枉过正。你有什么建议?
下面是我在做什么,现在古普塔的建议后使用MEF:
加了水果的信息类这样的:
abstract class FruitInfo
{
readonly Type type;
readonly string typeName;
public FruitInfo(Type type, string typeName)
{
this.type = type;
this.typeName = typeName;
}
}
创建每个水果一个FruitInfo类:
class Banana : Fruit
{
...
}
[Export(typeof(FruitInfo))]
class BananaInfo : FruitInfo
{
public BananaInfo() : base(typeof(Banana), "banana") { }
};
在Fruit中使用此静态函数导入类型:
public static void importAllFruitTypes()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
IEnumerable<FruitInfo> fruitInfos = container.GetExportedValues<FruitInfo>();
foreach(FruitInfo fruitInfo in fruitInfos) {
class[fruitInfo.typename] = fruitInfo.type;
}
}
任何改善此问题的建议仍然非常受欢迎。
如果我理解正确的话,那么你应该检查MEF(托管扩展框架),检查此链接http://msdn.microsoft.com/en-us/library/dd460648.aspx – 2012-07-25 11:15:20
感谢Gupta,MEF似乎是要走的路,发布它作为答案,以便我可以接受它。 – nobody 2012-07-26 07:57:05