2015-09-03 2 views
1

Я пытаюсь внедрить базовую систему загрузки модулей в своем приложении, где я использую Unity для обработки DI. Я думал, что будет легко использовать FileSystemWatcher и MEF для добавления динамической загрузки, но я столкнулся с проблемой.Сотрудничество Unity и MEF

Введение

При регистрации каталога с модулями ввода считанных модулей, которые в настоящее время присутствуют в каталоге и создать FileSystemWatcher

public List<IModule> RegisterModule(string directoryUri){ 
     var fsw = new FileSystemWatcher(directoryUri, "*.dll"); 
     fsw.Created += OnModulesChange; 
     fsw.EnableRaisingEvents = true; 

     return GetModules(); 
} 

В обработчике я обновить MEF каталоги каталогов и пожарной события уведомив, что контейнер изменился

private void OnModulesChange(object sender, FileSystemEventArgs e) 
{ 
    _catalog.Catalogs.OfType<DirectoryCatalog>().ForEach(x => x.Refresh()); 
    ModuleDirectoryChanged?.Invoke(this); 
    lastRead = DateTime.Now; 
} 

Каждый абонент, кроме r EADS новые модули снова через метод GetModules:

public List<IModule> GetModules() 
{ 
    var directories = _mefContainer.GetExports<IModule>().Select(x => x.Value).ToList(); 
    directories.ForEach(x => x.RegisterModule(this)); 
    return directories.Concat(_staticModules).ToList(); 
} 

В методе RegisterModule я некоторые разделяющим с Unity. Это довольно много логики сейчас, но в конце концов только Родственный метод я использую есть это:

public T Resolve<T>() where T : class, IMyThing 
{    
    return this._container.Resolve<T>(); 
} 

Проблема

Когда GetModules вызывается в первый раз, все работает (I просто используйте dll с модулем в каталоге при запуске приложения и зарегистрируйте каталог при запуске). Я могу установить точку останова на метод Resolve и увидеть, что все зарегистрировано и объект действительно разрешен.

Но когда я копирую другую .dll в каталог, то получаю ResolutionFailedException из метода Resolve. Если я посмотрю в контейнер, я вижу тип Регистрации, как и раньше. Один и тот же контейнер используется, вызывается один и тот же метод, единственное различие заключается в том, что вызов инициируется FileSystemWatcher.

Что я делаю неправильно? Это может быть систематическая проблема, поскольку я никогда не использовал MEF и Unity вместе, и у меня есть только ограниченное знание Unity.

Извините, если описание сбивает с толку, я попытаюсь устранить любые дополнительные вопросы.

Версия

  • .NET 4.5.2
  • Единство 3.5 (также попытались реферированием клонировали репозиторий Единства так базовый вариант)
  • МЕФ непосредственно из .NET 4.5.2 (не MEF 2)

ответ

1

Эти библиотеки могут быть использованы вместе, и вы можете, если вы хотите DI и расширяемость.

Проблема заключается в том, что контейнер Unity и каталог/контейнер MEF не знают друг о друге. Установите MefContrib.Integration.Unity на NuGet и вы можете заставить их работать вместе, используя этот код:

// Setup 
var unityContainer = new UnityContainer(); 
var aggregateCatalog = new AggregateCatalog(); 

// Register catalog 
unityContainer.RegisterCatalog(aggregateCatalog); 

Read More...

В приложении Prism, вы хотите сделать это в Bootstrapper как часть CreateContainer переопределения. Или MEF не сможет решить много вещей, которые Prism предоставляет Unity, например IUnityContainer, IEventAggregator или IRegionManager.

+0

Спасибо, это именно то, что мне нужно! –

0

Почему вы используете оба фреймворка одновременно? Unity и MEF - это менеджер по управлению зависимостями . Фреймы реализованы только по-разному и приносят преимущества и недостатки, следовательно, сами по себе.

Я надеюсь, что следующие ссылки могут помочь вам:

+0

Ну, единственная причина в том, что я использовал Unity в проекте еще до того, как начал внедрять модульную систему, и я узнал, что MEF выполняет именно то, что мне нужно «из коробки». Я пытаюсь посмотреть на Призм, но было бы намного лучше, если бы мне не пришлось менять мой контейнер IoC. Благодарю. Если в течение разумного времени больше не будет ответов, и я сделаю это, я отмечу это как ответ. Спасибо –

+0

Это не то же самое. Unity - это контейнер IoC, тогда как MEF предоставляет параметры расширяемости, такие как плагины. Или даже сторонние плагины. – Jammer

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