2014-11-18 2 views
1

Проблема, с которой я столкнулся: у меня есть класс Factory, который имеет список «Writer», «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

Вы смотрели в MEF на всех? – BradleyDotNET

+0

Не совсем, я не уверен, что это такое ... Я сделал быстрый поиск, но я не уверен, как это работает ... – Ken

+0

Похоже, вы хотите MEF; Я сделал заводы с этим, но мой подход, скорее всего, нарушит ваши требования. Не могли бы вы разместить несколько примеров кода, как вы хотите * использовать * завод? – BradleyDotNET

ответ

1

Это (как ни странно) основная цель MEF (Managed Extensibility Framework) [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.

+0

Вот и все! Ничего себе, спасибо :) – Ken

+0

@Ken не проблема; Рад, что я смог помочь. – BradleyDotNET

0

Я думаю, что вы говорите это плагин архитектуры.

Это может быть легко достигнуто с помощью контейнера Ioc, такого как Autofac или MEF (не только контейнер Ioc).

Я предпочел бы MEF в этом сценарии, так как он имеет лучшую поддержку для обнаружения типа.

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 (последняя реализация (четвёртая))

Смежные вопросы