Заполнить MEF-плагин конфигурационными данными

#c# #mef

#c# #mef

Вопрос:

Я борюсь с MEF и остановился на какой-то проблеме — в моем приложении у меня одноэлементный класс:

 class Config: IConfig {
}
  

в котором хранятся данные конфигурации приложения, загруженные, например, из XML-файлов, базы данных и т. Д

Теперь у меня есть несколько плагинов, которые должны иметь доступ к конфигурации, поэтому мне интересно, какое лучшее решение передать конфигурацию плагину?

Мое решение на данный момент таково:

 [ImportMany(typeof (IFieldPlugin))]
public IEnumerable<Lazy<IFieldPlugin, IFieldPluginData>> fieldPlugins;


foreach (var plugin in PluginsStorage.Instance.fieldPlugins)
{
    if (plugin.Metadata.Name.Equals(field.Plugin))
    {
        if(!plugin.IsValueCreated) {
            plugin.Value.Config = Config.Instance;
        }
        result = plugin.Value.DoStep(this,url);
    }
}
  

Есть решение получше?

Ответ №1:

Как насчет создания экземпляра класса Config на ранних этапах жизненного цикла приложения и экспорта оттуда?

Затем можно импортировать в конструкторе или как свойство.

Ответ №2:

Лучший способ сделать это — не обращаться к configuration manager через поле instance, а позволить MEF создать общий экземпляр, добавив PartCreationAttribute вот так

 [PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IConfig))]
class Config: IConfig {}
  

и добавить соответствующий импорт в ваши плагины. Пока тип конфигурации находится в каталоге, когда вы выполняете композицию, он должен быть просто установлен в ваших плагинах.

Ответ №3:

Обычно вы бы сделали что-то подобное; В сборке плагина:

 [Export(typeof(IPlugin))]
public class MyPlugin : IPlugin
{
    private readonly IConfig config;

    [ImportingConstructor]
    public MyPlugin(IConfig config)
    {
        if (config == null)
            throw new ArgumentNullException("config");
        this.config = config;
    }
}
  

В одной из основных сборок приложения:

 [Export(typeof(IConfig))]
public class Config : IConfig
{
   ...
}
  

Ответ №4:

Что я обычно делаю, так это создаю общую сборку для всех плагинов, куда я также добавляю контракты, в данном случае, например. IConfigurationManager.

Затем в загрузчике я создаю CompositionBatch, куда помещаю configuration manager, и поскольку все плагины знают об IConfigurationManager, я могу легко импортировать его, когда мне это нужно.

Комментарии:

1. у вас есть пример по этому поводу?