Как найти новые части MEF во время работы приложения?
Я использую MEF для загрузки плагинов в моем приложении. Все работает, но я хочу, чтобы новые части были обнаружены, когда они попали в папку моего приложения. Это возможно? В DirectoryCatalog есть событие Changed, но я не уверен, как он работает.
Это мой код прямо сейчас:
public sealed class RevealerFactory
{
private static readonly Lazy<RevealerFactory> lazy =
new Lazy<RevealerFactory>(() => new RevealerFactory());
public static RevealerFactory Instance { get { return lazy.Value; } }
private FileSystemWatcher watcher;
private RevealerFactory()
{
Initialize();
}
[ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)]
private IEnumerable<Lazy<IRevealer, IRevealerCapabilities>> Revealers {
get;
set;
}
public IRevealer GetRevealer(Uri uri)
{
return (from revealer in Revealers
where uri.Host.Equals(revealer.Metadata.Host,
StringComparison.OrdinalIgnoreCase)
&& revealer.Value.IsRevelable(uri)
select revealer.Value).FirstOrDefault();
}
private void Initialize()
{
var catalog = new DirectoryCatalog(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
+ "/SDownloader/Revealers");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
Ответы
Ответ 1
Вы можете использовать FileSystemWatcher, чтобы обнаружить новые DLL файлы, которые были удалены в вашей папке плагина. Затем вы можете обрабатывать такие события, вызывая DirectoryCatalog.Refresh
или AggregateCatalog.Catalogs.Add
обновить состав MEF новыми частями.
Некоторые вещи, о которых нужно знать:
-
Вам нужно отметить импорт MEF как предназначенный для решения проблемы перекомпоновки, как описано в разделе руководства по программированию MEF на Recomposition. В противном случае MEF вызовет ошибку при попытке обновить их.
-
FileSystemWatcher
вызывает события в потоках пула системных потоков (если вы не используете свойство SynchronizingObject
). Имейте в виду, что если вы вызываете DirectoryCatalog.Refresh
из другого потока, вы должны построить CompositionContainer
с включенным isThreadSafeFlag
. Вам также нужно будет подумать о безопасности потоков ваших свойств, которые будут вызываться при обновлении композиции.
-
Вы также можете удалить каталоги, выбирая их из коллекции AggregateCatalog.Catalogs
. Но нет способа выгрузить связанные сборки (за исключением выгрузки всего Appdomain
). Это также означает, что вы все еще не можете удалить или перезаписать сборку во время работы приложения.