2013-02-18 40 views
2

我在嘗試覆蓋企業庫的默認Unity容器行爲,以便可以使用我的MEF容器。有一個如何做到這一點的解釋一些資源,但我只是沒有得到它:在企業庫中使用MEFE

還有對左右,但這個職位代碼不會編譯,因爲LogWriter受保護。我認爲這指的是舊版本:

我的理解是,我需要使用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構造?我的MefContainerConfigurator。這是我應該將所有企業庫類型註冊到容器中的位置嗎?
  • 來自IServiceLocator接口的方法,我把它留作NotImplemented;我無法找到一種方法來使用它們從我的容器中返回對象。我是否應該讓他們沒有實現,並使用泛型方法呢?

編輯

我仍然不能得到這個完全正確的。基於@Chris Tavares的回答,我在MefContainerConfigurator中編寫了我的RegisterAll方法來迭代TypeRegistrations並將它們添加到容器中。我不能爲我的生活弄清楚如何將這些合併到我的AggregateContainer是在我Bootstrapper類創建,這樣我可以實際使用的這些出口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); 
    } 
} 

ConfigureAggregateCatalog在棱鏡引導程序:

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

回答

1

您的容器配置器非常不完整。你有一個方法來實現:RegisterAll,而你沒有實現它。

您不必從config讀取原始配置信息;相反,當你調用EnterpriseLibraryContianer.ConfigureContainer時,Entlib會旋轉配置源,挑選出所有重要的位,並向你提供一系列TypeRegistration對象。這些傢伙給你的類型映射,構造函數依賴等等。基本上你需要在你的容器中註冊依賴的所有東西(在這裏是MEF)。

因此,基本上你需要做的是編寫將抽象TypeRegistration對象轉換爲MEF的正確配置的代碼。

團結在這方面並不是特別的;它也有一個配置器,並遵循完全相同的流程,所以你可以在entlib代碼中查看你需要做的事情。

我根本不知道MEF apis,所以很遺憾不能幫你具體實現。

+0

謝謝,這指出我正確的方向爲RegisterAll方法。請參閱編輯修改後的問題,但我認爲您不能提供幫助,因爲它現在是MEF特有的。 – ChrisO 2013-02-28 10:17:35