在初始化时自动将类类型添加到工厂类
本文关键字:类型 添加 工厂 初始化 | 更新日期: 2023-09-27 18:30:47
我面临的问题:我有一个工厂类,它有一个"Writer"列表,"Writer"是一个抽象类(目前)。我创建了多个实现"编写器"类的类。有没有办法自动将派生类添加到工厂类的列表中?每个类型中的一个,或作为类型。最好不必将代码写入派生类(例如必须实现方法),最好不必调用方法(特别是对于每个单独的派生类)。
演示/示例:
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;
}
}
这是
(奇怪的是)MEF(托管扩展性框架)[ImportMany]
的主要目的。有关 MSDN 的文档。
要使用它,您首先需要标记 IWriter
接口的每个实现者
[Export(typeof(IWriter))]
这标志着它是 MEF 收集的类型(并且很容易忘记)。然后,您需要用[ImportMany]
标记您的收藏(writers
):
[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 页面。
我做了更多的研究,并使用工厂模式中的反射找到了更简单的答案。
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 次))
我认为您所说的是插件架构。
这可以通过像Autofac或MEF(严格来说不是Ioc容器)这样的Ioc容器很容易实现。
在这种情况下,我更喜欢 MEF,因为它对类型发现有更好的支持。