Как обнаружить новые детали MEF во время работы приложения? - PullRequest
12 голосов
/ 04 августа 2011

Я использую 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 Ответ

21 голосов
/ 05 августа 2011

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

Некоторые сведения, о которых следует знать:

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

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

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

...