根据http://docs.autofac.org/en/latest/integration/mef.html的文档使用时,Mef CompositionContainer
无法解析Autofac依赖关系。
我有一个大型代码库,它广泛使用ServiceLocator和单例......服务定位器通过使用缓存的System.ComponentModel.Composition.Hosting.CompositionContainer
完成所有对象创建,组合等。 (另请注意,我们目前正在使用/需要元数据支持)我正在尝试从此切换到更现代的架构。为此,现有的基于Mef(基于'CompositionContainer')的服务定位器必须与Autofac IoC容器配合使用。
以下功能
CompositionContainer
AutofacExport
扩展方法将.Exported
导出到MEF。抛出的异常是: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集成在一起。但是,我无法找到有关如何配置它的相关文档,并且该软件包没有太多用法。
答案 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解析。
我从来没有亲自使用过该软件包,但我认为如果您查看测试以及他们如何设置这些测试,它应该会让您继续使用。