【问题标题】:A metadata view must be a concrete class with a parameterless or dictionary constructor元数据视图必须是具有无参数或字典构造函数的具体类
【发布时间】:2015-03-10 17:37:31
【问题描述】:

System.Composition.Hosting.CompositionFailedException:类型 'ITranslatorMetaData' 不能用作元数据视图。元数据 视图必须是具有无参数或字典的具体类 构造函数。

我刚刚开始在 PCL 中使用 MEF(使用 nuget Microsoft.Composition)。我相信这是“轻量级”的 MEF。在我实施的课程中,我有

[Export(typeof(ITranslator))]
[ExportMetadata("Source", "Microsoft")]
[ExportMetadata("Order", "2")]

我有一个名为 ITranslatorMetaData 的接口

public interface ITranslatorMetaData
{
    [DefaultValue("Unknown")]
    string Source { get; }

    [DefaultValue(Int32.MaxValue)]
    int Order { get;  }
}

最后,我尝试使用

    [ImportMany]
    private Lazy<ITranslator, ITranslatorMetaData>[] _translators { get; set; }

我做错了什么?看起来这应该可以工作。

更新我试过这个没有用。

[Export(typeof(ITranslator)),
    ExportMetadata("Source", "Microsoft"),
    ExportMetadata("Order", "2")]

Update 2 我确实发现了一个错误,Order 应该是一个 int 而不是一个字符串。但是我在指定后仍然得到同样的错误

[Export(typeof(ITranslator)),
    ExportMetadata("Source", "Microsoft"),
    ExportMetadata("Order", 2)]

更新 3 一个提议的解决方案建议我不应该为元数据使用接口,尽管 http://mef.codeplex.com/wikipage?title=Exports%20and%20Metadata&referringTitle=Guide 中的 MEF 示例清楚地表明使用元数据的接口,而不是具体的类。

【问题讨论】:

  • 异常与该示例完全冲突:您尝试运行它吗?
  • 伟大的苏格兰人你是对的!
  • 永远不要完全相信一个例子而不先戳它。这不是我第一次遇到这样的问题(尽管我承认这是我第一次看到示例做了一些实际代码没有做的额外事情)

标签: c# mef


【解决方案1】:

正如例外所说,您必须为元数据使用具体类。

这意味着不允许使用 interfaceabstract class(编辑:还有 static class)类型,因为 MEF 代码在提取必要的元数据时不知道要构造什么。

因此,如果您像这样将interface ITranslatorMetaData 更改为class TranslatorMetaData

public class TranslatorMetaData
{
    [DefaultValue("Unknown")]
    string Source { get; set; }

    [DefaultValue(Int32.MaxValue)]
    int Order { get; set; }
}

代码可以编译。

关于构造函数,在没有其他构造函数的情况下假设了一个无参数的公共构造函数,这就是为什么上面的代码适合必要的参数。但是,指定带参数的构造函数会使类没有无构造函数参数,并导致相同的错误,除非使用错误中提到的“字典”构造函数。

【讨论】:

  • 普通MEF和轻量级MEF有区别吗?
  • 顺便说一句,我之前的代码也编译过,当它尝试拉取导入时会发生错误。随着您的代码更改,System.ObjectDisposedException:无法访问已处置的对象。对象名称:“根生命周期上下文”。
  • 根生命周期上下文,必须检查更多代码,可能查看您正在使用的确切库。至于区别,据我所知,MEF 上的文档表明 MEF 纯粹基于导入数据构造这些 MetaData 对象,并且由于您没有像实际导出那样指定具体类,它'不知道要做什么对象
  • 不知何故,它不喜欢以这种方式发送 TranslatorMetaData。当我尝试访问任何翻译器时,我遇到了已处理的对象问题。
  • 私有 IEnumerable 没有问题 _translators { get;放; } 虽然
猜你喜欢
  • 2015-07-04
  • 2014-05-18
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多