【问题标题】:MEF - [ImportMany] using ExportFactory<T> in WPF - .NET 4.0MEF - [ImportMany] 在 WPF - .NET 4.0 中使用 ExportFactory<T>
【发布时间】:2012-09-10 21:40:56
【问题描述】:

我有一些需要创建多个实例的部分导入。通过四处搜索,我决定我需要使用 ExportFactory 类。不幸的是,默认情况下,ExportFactory 类在 WPF 中不可用,但幸运的是 Glenn Block 有 ported the code

原来,我是在导入时指定类型:

[ImportMany(typeof(IMyModule))]
public IEnumerable<Lazy<IMyModule, IMyModuleMetadata>> Modules { get; set; }

我还创建了一个导出属性:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportMyModuleMetadata : ExportAttribute, IMyModuleMetadata
{
    public ExportMyModuleMetadata(string category, string name)
        : base(typeof(IMyModuleData))
    {
        Category = category;
        Name = name;
    }
    public string Category { get; set; }
    public string Name { get; set; }
}

我的导出如下所示:

[ExportMyModuleMetadata("Standard","Post Processor")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Module1 : IMyModuleData

上述导入工作正常。但是一旦我将Lazy&lt;T,T&gt; 更改为ExportFactory&lt;T,T&gt;,我开始在合成过程中遇到错误。

[ImportMany(typeof(IMyModule))]
public IEnumerable<ExportFactory<IMyModule, IMyModuleMetadata>> Modules { get; set; }

我得到的错误信息是:

The export 'Module1 (ContractName="IMyModule")' is not assignable to type
'System.ComponentModel.Composition.ExportFactory`

我在某处看到(我现在找不到链接)在ImportMany 属性中指定Type 是问题所在。我想我可以不用它,所以我从 ImportMany 中删除了该类型。

[ImportMany()]
public IEnumerable<Lazy<IMyModule, IMyModuleMetadata>> Modules { get; set; }

这个导入在使用Lazy&lt;T,T&gt; 时仍然有效,但是一旦我将它更改为ExportFactory&lt;T,T&gt;,我就不再导入任何东西。我不再收到错误消息,但没有导入任何内容。

有谁知道如何在 WPF 中正确使用 ImportManyExportFactory&lt;T,T&gt;

更新:

根据 Wes 关于添加 ExportFactoryProvider() 的提示,我得到了在 .NET 4 中工作的 ExportFactory&lt;T,T&gt;!以下是更新后的合成代码。

var ep = new ExportFactoryProvider();

//Looks for modules in main assembly and scans folder of DLLs for modules.
var moduleCatalog = new AggregateCatalog(
    new AssemblyCatalog(runningApp),
    new DirectoryCatalog(".", "*.dll"));
var container = new CompositionContainer(moduleCatalog, ep);
ep.SourceProvider = container;
var Modules = new Modules();
container.ComposeParts(Modules);

我还在MEF Codeplex site 找到了一个关于此的讨论,其中对此进行了更多讨论。

【问题讨论】:

  • 记得应用天空驱动文件 cmets 中提到的 Jean-Phillipe Leconte 的修复:在第 115 行的 ExportFactoryInstantiationProvider 中: if (cbid == null || !cbid.RequiredTypeIdentity.StartsWith(PartCreatorContractPrefix)) 应该是: if (cbid == null || cbid.RequiredTypeIdentity == null || !cbid.RequiredTypeIdentity.StartsWith(PartCreatorContractPrefix)) 因为RequiredTypeIdentity (cbid.RequiredTypeIdentity) 在没有所需类型时为空(仅按名称导入),因此在空字符串上调用 StartsWith。

标签: c# wpf mef


【解决方案1】:

一般来说,.NET 4.0 ExportFactory 不支持开箱即用。 ExportFactory 是容器(或自定义导出提供程序)知道并特别处理的特殊类型,并且根据您收到的错误消息,它看起来并不像此容器对 ExportFactory 有任何特殊了解,因为它试图将其转换为 IMyModule .

看看 Glen 对 ExportFactory 的测试,您是否将 Microsoft.ComponentModel.Composition.Hosting.ExportFactoryProvider 添加到您的容器中?

另请注意,如果您可以选择切换到 .NET 4.5,ExportFactory 支持开箱即用。

【讨论】:

  • 我没有添加ExportFactoryProvider。我现在正在查看示例项目。除了查看这个可能有帮助的示例项目之外,还有关于ExportFactory&lt;T,T&gt; 的任何文档吗?在线浏览寻求帮助时,我从未看到任何关于 ExportFactoryProvider 的信息。
  • 添加ExportFactoryProvider 解决了这个问题!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多