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>();