【问题标题】:Custom 'ExportFactory'自定义“出口工厂”
【发布时间】:2010-12-11 15:37:10
【问题描述】:

使用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);

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

可以在here找到一个示例项目(带有无参数构造函数)。

【问题讨论】:

  • 我很困惑。您谈论MyExportFactory,但随后您展示了一个名为SrviceProviderFactory 的类。您还定义了一个方法CreateServiceProvider,然后在其他地方调用CreateMyExport。你在写问题时重命名了吗?

标签: c# export mef factory


【解决方案1】:

当 MEF 看到 ExportFactory<IFoo> 类型的导入时,它会以特殊方式处理它。它不是从字面上寻找ExportFactory<IFoo> 导出,而是寻找IFoo 导出并神奇地为该类型生成一个工厂。

您的错误是您希望这种魔法也能自动为您自己的替代 ExportFactory 工作,您称之为 SrviceProviderFactory。这不是真的。当您在某处导入 SrviceProviderFactory<IFoo,IFooMetadata> 时,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<IServiceProviderFactory,IDictionary<string,object>>[] Factories 
    {
        get;
        set;
    }

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

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

这就是为什么I already suggested you export Func instead,但显然你不喜欢这个答案。

您也可以尝试复制ExportFactory 魔法。这是可能的,但是 MEF 的一个非常高级的用例。如果您想这样做,我建议您查看 ExportFactoryProvider 的 MEF 源代码,了解如何构建您自己的支持参数的实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 2017-11-03
    • 2013-02-06
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多