我面临的问题:我有一个Factory类,其中有一个" Writer" s,#34; Writer"是一个抽象类(现在)。我创建了多个实现" Writer"类。是否有办法自动将派生类添加到Factory类的列表中?每个中的任何一个,或作为类型。最好不必将代码写入派生类(如必须实现方法),最好不必调用方法(特别是对于每个单独的派生类)。
演示/示例:
interface IWriter {
void Write(string text);
}
class BlockWriter : IWriter {
//something like this maybe, only this only calls on use of the class so it doesn't work...
//static BlockWriter() {
// Factory.Add(new BlockWriter());
//}
public void Write(string text) {
Console.WriteLine("Block: " + text);
}
}
class Factory {
private static List<IWriter> writers = new List<IWriter>();
public static List<IWriter> GetWriters() { return writers; }
// I don't want to have to write every single one down like this.
// I want a way to do this automatically, like withing the derived classes.
public static void Build() {
writers.Add(new BlockWriter());
writers.Add(new ColumnWriter());
writers.Add(new LineWriter());
writers.Add(new SpiralWriter());
writers.Add(new WaveWriter());
}
static Factory() {
Build();
}
public static IWriter ChooseWriter(string input) {
foreach (IWriter w in writers)
if (w.GetType().Name.Equals(input))
return w;
return null;
}
}
答案 0 :(得分:1)
这是(奇怪的)MEF(托管可扩展性框架)[ImportMany]
的主要目的。有关MSDN的文档。
要使用它,首先需要使用
标记IWriter
接口的每个实现者
[Export(typeof(IWriter))]
这标志着它是MEF收集的一种类型(并且非常容易忘记)。然后,您需要使用writers
[ImportMany]
)
[ImportMany]
private static List<IWriter> writers;
最后,您需要为程序集设置合成容器,然后调用ComposeParts
。 MEF将获取它找到的所有导出匹配标记为[ImportMany]
的列表的泛型参数类型的导出,并使用每个匹配的单个实例填充列表出口类型。
//An aggregate catalog that combines multiple catalogs
AggregateCatalog catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the Factory class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Factory).Assembly));
//Create the CompositionContainer with the parts in the catalog
CompositionContainer container = new CompositionContainer(catalog);
//Fill the lists
_container.ComposeParts(this);
大部分代码来自链接的MSDN页面。
答案 1 :(得分:1)
我已经做了一些研究,并在工厂模式中使用反射找到了一个更简单的答案。
public static IWriter ChooseWriter(string writer)
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
var currentType = currentAssembly.GetTypes().SingleOrDefault(t => t.Name == writer);
return (IWriter )Activator.CreateInstance(currentType);
}
http://techtaunt.wordpress.com/2011/06/15/factory-pattern-with-reflection-c/或 http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern(最后一次实施(第4次))
答案 2 :(得分:0)