自定义’ExportFactory’

使用MEF的桌面应用程序导入许多“ServiceProviders”。 每个部分(ServiceProvider)都是一个单独的DLL内的类。 所有DLL都在“插件”文件夹中,供桌面应用程序使用。

由于我需要新部件的实例,因此ExportFactory是最佳选择。 问题是我的部件有构造函数。 我需要将一些参数传递给ExportFactory (MEF2,Preview2)不支持的部件的构造函数。

我需要这样的东西:

 // Each part has its own dependency Dependency dependency = LoadDependency(myPart.Metedata["Name"]); // Injecting dependency into part's constructor myPart.CreateExport(dependency); 

我不想从我的零件方面导入任何东西。

可以在此处找到示例项目(带无参数构造函数)。

当MEF看到ExportFactory类型的导入时,它会以特殊方式处理它。 它不是按字面意思查找ExportFactory导出,而是查找IFoo导出,并神奇地为该类型生成工厂。

你的错误在于你希望这个魔法也可以自动用于你自己的ExportFactory替代ExportFactory ,你可以ExportFactory它命名为SrviceProviderFactory 。 这不是真的。 当您在某处导入SrviceProviderFactory ,MEF会逐字地查找该类型的导出。

直接的解决方案是给它这个出口。 为每个IServiceProvider实现手动导出工厂。 例如,如果您有一个FooServiceProvider

 public class FooServiceProvider : IServiceProvider { public FooServiceProvider(Dependency dependency) { ... } } 

然后你还需要一个FooServiceProviderFactory:

 [Export(typeof(IServiceProviderFactory))] [ExportMetaData("foo", "bar")] public class FooServiceProviderFactory : IServiceProviderFactory { public IServiceProvider CreateServiceProvider(Dependency d) { return new FooServiceProvider(d); } } 

然后您的导入器可以根据元数据选择正确的工厂:

 public class FactoryUser { [ImportMany] public Lazy>[] Factories { get; set; } public void DoSomething() { var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value; var serviceProvider = factory.CreateServiceProvider(someDependency); ... } } 

这里令人讨厌的是,对于每个服务提供者实现,您还需要创建和导出工厂实现。 您可以通过创建公共工厂基类(如SrviceProviderFactory )来节省工作,但仍然必须派生特定的类,因为您不能在MEF导出中使用generics类型参数。 更新 :我相信.NET 4.5现在支持导出开放generics类型。

这就是为什么我已经建议你输出Func ,但显然你不喜欢那个答案。

您还可以尝试复制ExportFactory魔术。 这是可能的,但是MEF的一个非常先进的用例。 如果你想这样做,我建议你看一下ExportFactoryProvider的MEF来源,看看如何构建你自己的实现并支持参数。