Ленивая загрузка DLL с MEF - PullRequest
       0

Ленивая загрузка DLL с MEF

5 голосов
/ 07 декабря 2010

Я делаю свой первый проект с MEF и серьезно не могу понять, как использовать отложенную загрузку.Мой код -

public static class MefLoader
{
     private static CompositionContainer Container;

    [ImportMany(typeof(IControlModule), AllowRecomposition = true)]
    private static IEnumerable<Lazy<IControlModule, IImportComponentCapabilites>> 
               DllList { get; set; }

    static MefLoader()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new DirectoryCatalog("."));
        Container = new CompositionContainer(catalog);

    }

Я понимаю большую часть того, как использовать MEF, за исключением того, что я не вижу, как инициализировать объект DllList.Я хочу использовать ленивую загрузку, потому что в финальной системе у нас очень много вариантов, и только около 10% будут использоваться одновременно.

Ответы [ 3 ]

6 голосов
/ 07 декабря 2010

Сначала вы пытаетесь импортировать объекты в статическое свойство.Это не поддерживается MEF: MEF составляет объекты , а не классы .Если вы хотите инициализировать статические свойства, вы должны сделать это вручную следующим образом:

DllList = container.GetExports<IControlModule, IImportComponentCapabilites>();

Теперь о отложенной загрузке: DirectoryCatalog создает AssemblyCatalog для каждой сборки в каталоге.Реализация AssemblyCatalog в MEF будет перечислять все типы в сборке, как только будет вызван AssemblyCatalog.Parts, что произойдет, когда вы извлечете экспорт из контейнера.Это означает, что сборка загружается еще до того, как MEF определит, что она содержит деталь, которая ей действительно необходима.

Для того, чтобы действительно иметь отложенную загрузку сборок, потребуется информация о том, какие детали доступны в этих сборкахбыть кэшированным где-то.MEF в настоящее время не имеет такого встроенного механизма кэширования из коробки.Однако в примерах, включенных в исходный код MEF в codeplex *, есть реализация ComposablePartCatalogAssemblyCache.

Единственное, что делает Lazy<T>, это откладывает момент, когда конструктор части называется.Это уже может ускорить процесс, но не откладывает загрузку сборок.

1 голос
/ 07 декабря 2010

Самое замечательное в MEF (по умолчанию) вы не инициализируйте объект; MEF будет сопоставлять любые объявленные [Экспорт], которые соответствуют вашему импорту, а затем MEF их для вас. Если ваши зависимости сами имеют зависимости, MEF будет продолжать цепочку, пока не будет решен весь ваш график.

Использование Lazy (в отличие от T) просто означает, что создание экземпляров будет отложено до тех пор, пока вы не получите доступ к этой зависимости. Если, возможно, вы отлаживаете и не видите, когда эта зависимость инициализируется, вам нужно получить доступ к свойству Value, чтобы начать создание экземпляра.

Существуют некоторые большие различия между MEF и большинством других контейнеров IoC (поскольку MEF фокусируется только на расширяемости / компоновке), но это похоже на то, как контейнер IoC после регистрации типа будет создавать экземпляр зависимости, когда вы разрешить что-то

Если вам интересно, как можно изменить некоторые из функций создания экземпляров, здесь есть некоторые подробности о политиках создания: http://mef.codeplex.com/wikipage?title=Parts%20Lifetime

0 голосов
/ 23 сентября 2016

Это действительно старый вопрос, но для тех, кто ищет решение, я недавно внедрил LazyAssemblyCatalog, который позволяет лениво загружать сборки плагинов, в то же время делая метаданные плагина доступными без загрузить эти сборки. Его концепция очень похожа на CachedAssemblyCatalog, который @Wim упомянул в своем ответе. Надеюсь, это кому-нибудь поможет.

...