将MEF与企业库结合使用
本文关键字:结合 企业库 MEF | 更新日期: 2023-09-27 17:59:44
我正在尝试覆盖企业库的默认Unity容器行为,以便使用我的MEF容器。有一些资源可以解释如何做到这一点,但我只是不明白:
- http://blogs.msdn.com/b/bobbrum/archive/2009/06/23/enterprise-library-5-0-some-architecture-changes.aspx
- http://entlib.uservoice.com/forums/90505-silverlight-integration-pack/suggestions/1284693-mef-configurator-for-enterprise-library-container
- http://entlib.codeplex.com/discussions/261443
SO上也有这篇文章,但由于LogWriter
受到保护,代码没有编译。我认为这是指一个旧版本:
- 带有Enterprise Library 5.0的.net Mef
我所理解的是,我需要将CommonServiceLocator
用于我的MEF容器,然后将其附加到企业库容器。以下是我的容器配置程序:
public class MefContainerConfigurator : IContainerConfigurator, IServiceLocator
{
[Import] private CatalogExportProvider provider;
public object GetService(Type serviceType)
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType)
{
return provider.GetExportedValue<Type>();
}
public object GetInstance(Type serviceType, string key)
{
throw new NotImplementedException();
}
public IEnumerable<object> GetAllInstances(Type serviceType)
{
throw new NotImplementedException();
}
public TService GetInstance<TService>()
{
return provider.GetExportedValue<TService>();
}
public TService GetInstance<TService>(string key)
{
return provider.GetExportedValue<TService>(key);
}
public IEnumerable<TService> GetAllInstances<TService>()
{
return provider.GetExportedValues<TService>();
}
public void RegisterAll(IConfigurationSource configurationSource, ITypeRegistrationsProvider rootProvider)
{
throw new NotImplementedException();
}
}
在我的引导程序中:
var configurator = new MefContainerConfigurator();
// Does this line read the Enterprise Library configuration from the app.config?
IConfigurationSource cs = new SystemConfigurationSource();
EnterpriseLibraryContainer.ConfigureContainer(configurator, cs);
我想也许我需要使用LogWriterImpl
和ExceptionManagerImpl
类,因为它们有接受配置的构造函数。在这一点上,我的问题是:
- 如何从
IConfigurationSource
检索配置并将其提供给LogWriterImpl
和ExceptionManagerImpl
构造函数 EnterpriseLibraryContainer.ConfigureContainer
调用我的MefContainerConfigurator
中的RegisterAll
。这是我应该将所有企业库类型注册到容器中的地方吗- 来自
IServiceLocator
接口的方法,我将其保留为NotImplemented;我找不到使用这些从容器中返回对象的方法。我是不是应该让它们没有实现,而是使用泛型方法
编辑
我仍然不能完全正确。基于@Chris Tavares的回答,我在MefContainerConfigurator
中编写了RegisterAll
方法,以迭代TypeRegistrations并将它们添加到容器中。我一辈子都不知道如何将这些合并到我的Bootstrapper
类中创建的AggregateContainer
中,这样我就可以在ContainerConfigurator
:之外实际使用这些导出
public void RegisterAll(IConfigurationSource configurationSource, ITypeRegistrationsProvider rootProvider)
{
var registrations = rootProvider.GetRegistrations(configurationSource);
foreach (var type in registrations)
{
var builder = new RegistrationBuilder();
builder.ForType(type.ServiceType).Export();
var cat = new AssemblyCatalog(type.ServiceType.Assembly, builder);
var container = new CompositionContainer(cat);
container.ComposeParts(this);
}
}
配置Prism引导程序中的聚合目录:
protected override void ConfigureAggregateCatalog()
{
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(RegionNames).Assembly));
// Module assemblies
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(DataEntryModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ReportingModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(StatusBarModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(SplashScreenModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(WelcomeModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(AdministrationModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
}
您的容器配置程序非常不完整。你有一个方法要实现:RegisterAll,但你没有实现它
您不必从config中读取原始配置信息;相反,当您调用EnterpriseLibraryContianer时,会发生这种情况。ConfigureContainer,Entlib将遍历配置源,挑选出所有重要的部分,并递给您一系列TypeRegistration对象。这些家伙为您提供了类型映射和构造函数依赖关系等。基本上,您需要在容器(在本例中为MEF)中注册依赖关系的所有东西。
因此,基本上您需要做的是编写代码,将抽象的TypeRegistration对象转换为MEF的正确配置。
团结在这方面并不特别;它也有一个配置程序,并遵循完全相同的过程,因此您可以在entlib代码中查看您需要做的各种事情的示例。
我根本不知道MEF api,所以很遗憾不能帮助您进行具体的实现。