Mef2 Настройка регистрации в каждом модуле

Итак, я использую Caliburn Micro и Mef2 в приложении C# WPF с использованием.Net 4.5. Я задаюсь вопросом, есть ли какой-нибудь способ, которым я могу настроить свои регистрации для Mef2 в отдельных dll и затем использовать их в моей основной dll. В основном DLL будет настраивать собственный импорт и экспорт.

Что-то вроде:

RegistrationBuilder builder = new RegistrationBuilder();

        builder.ForTypesDerivedFrom<IShell>().Export<IShell>().SetCreationPolicy(CreationPolicy.Shared);
        builder.ForTypesDerivedFrom<IFindProducts>().Export<IFindProducts>().SetCreationPolicy(CreationPolicy.Shared);
        builder.ForTypesMatching(t => t.Name.EndsWith("ViewModel")).Export().SetCreationPolicy(CreationPolicy.NonShared);

        return builder;

в каждой DLL, но я застрял в точке слияния всех регистраций в один RegistrationBuilder, чтобы затем перейти в каждый каталог.

1 ответ

Решение

Подход заключается в том, чтобы передать RegistrationBuilder каждой сборке для обновления. Это можно сделать, добавив такой интерфейс:

public interface IRegistrationUpdater
{
    void Update(RegistrationBuilder registrationBuilder);
}

в договоре сборки. На эту ссылку будут ссылаться все сборки, которые должны зарегистрировать конвенции MEF2. Например:

public class RegistrationUpdater: IRegistrationUpdater
{
    public void Update(RegistrationBuilder registrationBuilder)
    {
        if (registrationBuilder == null) throw new ArgumentNullException("registrationBuilder");

        registrationBuilder.ForType<SomeType>().ImportProperty<IAnotherType>(st => st.SomeProperty).Export<ISomeType>();
        registrationBuilder.ForType<AnotherType>().Export<IAnotherType>();
    }
}

с SomeType реализации ISomeType а также AnotherType реализации IAnotherType, IAnotherType не нуждается в деталях. ISomeType нужен IAnotherType часть.

Затем в вашей основной программе вам нужно найти доступные IRegistrationUpdaters, используя что-то вроде:

static IEnumerable<IRegistrationUpdater> GetUpdaters()
{            
    var registrationBuilder = new RegistrationBuilder();
    registrationBuilder.ForTypesDerivedFrom<IRegistrationUpdater>().Export<IRegistrationUpdater>();
    using (var catalog = new DirectoryCatalog(".", registrationBuilder))
    using (var container = new CompositionContainer(catalog))
    {
        return container.GetExportedValues<IRegistrationUpdater>();
    }  
}

который затем может быть использован для перебора каждого средства обновления и вызова IRegistrationUpdater.Update(RegistrationBuilder),

var mainRegistrationBuilder = new RegistrationBuilder();
foreach (var updater in GetUpdaters())
{
    updater.Update(mainRegistrationBuilder);
}

var mainCatalog = new DirectoryCatalog(".", mainRegistrationBuilder);
var mainContainer = new CompositionContainer(mainCatalog);

var s = mainContainer.GetExportedValue<ISomeType>();
Другие вопросы по тегам