Microsoft Extensibility Framework - MEF CompositionContainer - PullRequest
0 голосов
/ 14 января 2011

Я нахожусь в процессе создания службы Windows, которая реализует MEF.Идея состоит в том, что сервис должен управлять подкомпонентами и быть подключаемым, когда любое количество новых компонентов может быть введено во время выполнения без необходимости полного сценария перекомпиляции и развертывания сервиса.Компоненты должны быть подключаемыми. Это означает, что как только я перенесу выходную сборку в назначенную папку на диске, служба Windows должна сказать «Эй, вот новый компонент для запуска ...» и просто сделать свое дело.Это сила MEF.Пока очень крутые вещи.

Я понимаю концепцию создания AggregateCatalog и CompositionContainer для импорта всех доступных подкомпонентов (сборок).Это все хорошо, и работает, как и ожидалось, когда служба Windows запускается изначально.Однако в конечном итоге я собираюсь представить новые компоненты во время выполнения, поэтому в какой-то момент мне понадобится CompositionContainer для распознавания любых новых выходных сборок, которые добавлены.

Меня беспокоит то, что сказывается на производительности.Безопасно / эффективно ли помещать логику CompositionContainer в цикл, такой как:

        [ImportMany(AllowRecomposition = true)]
        private IEnumerable<Lazy<IMySubComponentTask, IDictionary<string, object>>>                        
        MySubComponentTasks { get; set; }

        while (true)
        {
          //Create a general aggregate catalog
          var catalog = new AggregateCatalog();

          //Adds all the parts found in the same assembly as the Program class
          catalog.Catalogs.Add(new AssemblyCatalog(typeof(MySubComponentTaskFactory).Assembly));

          //Create a new directory catalog
          var directoryCatalog = new DirectoryCatalog(@".\Extensions");

          //Add the DLLs in the directory to the aggregate catalog
          catalog.Catalogs.Add(directoryCatalog);

          //Create the current composition container to create the parts
          var container = new CompositionContainer(catalog);

          //Fill the imports of this object
          try
          {
            container.ComposeParts(this);
          }
          catch (CompositionException compositionException)
          {
            Console.WriteLine(compositionException.ToString());
          }
       }

Любая обратная связь или вход приветствуются.

Спасибо, Майк

Ответы [ 2 ]

1 голос
/ 14 января 2011

Нет, я бы не стал создавать экземпляр каталога в цикле.Тем не менее, возможно System.Timers.Timer или System.Threading.Timer для периодической проверки каталога плагинов - в зависимости от того, что вам больше подходит.

Поскольку ваша ImportMany позволяет перекомпоновку, вы сможете добавлять новые композиции во время выполнения:

Timer checkPlugin = new Timer();

//set CheckForPlugins as a timer callback or action
void CheckForPlugins()
{
    // add plugins catalog if found in directory
}

Я нашел некоторую дополнительную информацию: Рекомпозиция и конструкторы

0 голосов
/ 14 января 2011

Создание CompositionContainers должно быть дешевым.Создание каталогов не так дешево, потому что сборки должны быть проверены, чтобы найти детали MEF.Поэтому вы должны создать каталог вне цикла, если это возможно.

...