在初始化时自动将class-type添加到工厂类

时间:2014-11-18 20:02:53

标签: c# .net

我面临的问题:我有一个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;
    }
}

3 个答案:

答案 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)

我认为你所谈论的是一个插件架构。

使用像AutofacMEF(非严格意义上的Ioc容器)这样的Ioc容器可以很容易地实现这一点。

我更喜欢MEF,因为它更好地支持类型发现。