Подтвердить что ты не робот

Как найти новые части 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);
    }
}
4b9b3361

Ответ 1

Вы можете использовать FileSystemWatcher, чтобы обнаружить новые DLL файлы, которые были удалены в вашей папке плагина. Затем вы можете обрабатывать такие события, вызывая DirectoryCatalog.Refresh или AggregateCatalog.Catalogs.Add обновить состав MEF новыми частями.

Некоторые вещи, о которых нужно знать:

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

  • FileSystemWatcher вызывает события в потоках пула системных потоков (если вы не используете свойство SynchronizingObject). Имейте в виду, что если вы вызываете DirectoryCatalog.Refresh из другого потока, вы должны построить CompositionContainer с включенным isThreadSafeFlag. Вам также нужно будет подумать о безопасности потоков ваших свойств, которые будут вызываться при обновлении композиции.

  • Вы также можете удалить каталоги, выбирая их из коллекции AggregateCatalog.Catalogs. Но нет способа выгрузить связанные сборки (за исключением выгрузки всего Appdomain). Это также означает, что вы все еще не можете удалить или перезаписать сборку во время работы приложения.