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

我想也许我需要使用LogWriterImplExceptionManagerImpl类,因为它们有接受配置的构造函数。在这一点上,我的问题是:

  • 如何从IConfigurationSource检索配置并将其提供给LogWriterImplExceptionManagerImpl构造函数
  • 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));
}

将MEF与企业库结合使用

您的容器配置程序非常不完整。你有一个方法要实现:RegisterAll,但你没有实现它

您不必从config中读取原始配置信息;相反,当您调用EnterpriseLibraryContianer时,会发生这种情况。ConfigureContainer,Entlib将遍历配置源,挑选出所有重要的部分,并递给您一系列TypeRegistration对象。这些家伙为您提供了类型映射和构造函数依赖关系等。基本上,您需要在容器(在本例中为MEF)中注册依赖关系的所有东西。

因此,基本上您需要做的是编写代码,将抽象的TypeRegistration对象转换为MEF的正确配置。

团结在这方面并不特别;它也有一个配置程序,并遵循完全相同的过程,因此您可以在entlib代码中查看您需要做的各种事情的示例。

我根本不知道MEF api,所以很遗憾不能帮助您进行具体的实现。