根据文档

时间:2015-06-22 15:49:50

标签: c# mef autofac

根据http://docs.autofac.org/en/latest/integration/mef.html的文档使用时,Mef CompositionContainer无法解析Autofac依赖关系。

我有一个大型代码库,它广泛使用ServiceLocator和单例......服务定位器通过使用缓存的System.ComponentModel.Composition.Hosting.CompositionContainer完成所有对象创建,组合等。 (另请注意,我们目前正在使用/需要元数据支持)我正在尝试从此切换到更现代的架构。为此,现有的基于Mef(基于'CompositionContainer')的服务定位器必须与Autofac IoC容器配合使用。

以下功能

  1. 创建Mef CompositionContainer
  2. 证明MEF能够解决简单的导出问题
  3. 配置Autofac注册MEF并使用AutofacExport扩展方法将.Exported导出到MEF。
  4. 证明Autofac可以使用Autofac中的依赖项definend解析mef组件
  5. 证明Mef无法使用Autofac依赖关系解析导出的组件组件。
  6. 抛出的异常是:ImportCardinalityMismatchException("No exports were found that match the constraint: ContractName MefExportWithDependency RequiredTypeIdentity MefExportWithDependency"被抛出。

    public void MefResolve_ObjectWithDependency_CanResolveWhenAutofacRegistersDependeyncy2()
    {
        //1. Initialize Mef
        var composablePartCatalogs = new List<ComposablePartCatalog>
        {
            new AssemblyCatalog(Assembly.GetExecutingAssembly())
            //A lot more here..
        };
    
        var aggregateCatalog = new AggregateCatalog(composablePartCatalogs);
        var container = new CompositionContainer(aggregateCatalog, true);
        //2. As expected this is resolved
        container.GetExport<MefExport>().Should().NotBeNull();
    
        //3. Initialize Autofac
        var builder = new ContainerBuilder();
        builder.Register(c => new AutofacExport()).Exported(x => x.As<AutofacExport>());
        builder.RegisterComposablePartCatalog(aggregateCatalog);
    
        var ioc = builder.Build();
    
        //4. Here Autofac is correctly providing the dependency to the mef ImportingConstructor
        ioc.Resolve<MefExportWithDependency>().AutofacExport.Should().NotBeNull();
    
        //5. The next line will throw ImportCardinalityMismatchException
        container.GetExport<MefExportWithDependency>();
    }
    

    上面的代码需要定义以下类:

    public class AutofacExport { }
    
    [Export]
    public class MefExport { }
    
    [Export]
    public class MefExportWithDependency
    {
        public AutofacExport AutofacExport { get; set; }
    
        [ImportingConstructor]
        public MefExportWithDependency(AutofacExport autofacExport)
        {
            AutofacExport = autofacExport;
        }
    }
    

    注意: 我还看了https://www.nuget.org/packages/MefContrib.Integration.Autofac/ - 它承诺将Mef与Autofac集成在一起。但是,我无法找到有关如何配置它的相关文档,并且该软件包没有太多用法。

1 个答案:

答案 0 :(得分:0)

我认为你可能误解了Autofac.Mef包应该起作用的方式。虽然它将MEF项目带入Autofac,但让Autofac了解MEF目录中注册的导出/导入属性和项目,它是单向操作 - 它不会将Autofac注册推入MEF或允许MEF CompositionContainer使用Autofac

我相信你想要的是你提到的MefContrib.Integration.Autofac,它似乎允许事物向另一个方向流动 - 从Autofac到MEF。

查看其工作原理的好地方是在他们的存储库中,他们有some unit tests显示MEF正在解析Autofac项目的集成。这是一个这样的测试:

[Test]
public void ExportProviderResolvesServiceRegisteredByTypeTest()
{
    // Setup
    var builder = new ContainerBuilder();
    builder.RegisterType<AutofacOnlyComponent1>().As<IAutofacOnlyComponent>();
    var autofacContainer = builder.Build();
    var adapter = new AutofacContainerAdapter(autofacContainer);
    var provider = new ContainerExportProvider(adapter);

    var component = provider.GetExportedValue<IAutofacOnlyComponent>();
    Assert.That(component, Is.Not.Null);
    Assert.That(component.GetType(), Is.EqualTo(typeof(AutofacOnlyComponent1)));
}

正如您所看到的,他们有一个适用于Autofac容器的适配器,可以转换&#34;转换&#34;他们成为MEF可以理解的东西。他们还有some unit tests showing bi-directional integration - MEF从Autofac解析,Autofac从MEF解析。

我从来没有亲自使用过该软件包,但我认为如果您查看测试以及他们如何设置这些测试,它应该会让您继续使用。