Gre*_*oud 15 .net c# mef c#-4.0
我有一个界面:
[InheritedExport(typeof(IMetric))]
public interface IMetric { ... }
Run Code Online (Sandbox Code Playgroud)
我有一个Meta属性界面:
public interface IMetricAttribute { ... }
Run Code Online (Sandbox Code Playgroud)
以及实现它的属性:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class MetricAttribute : ExportAttribute, IMetricAttribute {
public string MetricName { get; set; }
public string MetricDescription { get; set; }
public MetricAttribute(string name, string description)
: base(typeof(MetricAttribute)) {
this.MetricName = name;
this.MetricDescription = description;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有两个班:
[Metric("MetricA","MetricA")]
public class MetricA: IMetric { ... }
[Export(typeof(IMetric))] <<<< THIS IS IMPORTANT
[Metric("MetricB", "MetricB")]
public class MetricB: IMetric { ... }
Run Code Online (Sandbox Code Playgroud)
然后我尝试导入指标(我可以在目录中看到)
以下返回MetricA AND MetricB
var metrics = compositionContainer.GetExports<IMetric>();
Run Code Online (Sandbox Code Playgroud)
但是,以下仅返回MetricB和NOT MetricA
var metrics = compositionContainer.GetExports<IMetric, IMetricAttribute>();
Run Code Online (Sandbox Code Playgroud)
任何想法为什么?
(注意MetricB上的重复导出(它已经实现了IMetric))
谢谢
大卫
Mat*_*ott 14
我第一次看到这种行为,但根据我的理解,元数据是在类型级别的每次导出生成的.所以,给定:
[Metric("MetricA", "MetricA")]
public class MetricA : IMetric
{
}
Run Code Online (Sandbox Code Playgroud)
您有两种此类型的导出.您的导出MetricA是由您自己提供的MetricAttribute,并且您具有IMetric由InheritedExport(typeof(IMetric))接口上的属性提供的继承导出.
如果查看容器,您会注意到为其定义了两个导出MetricA.这是第一个带有元数据的:

这是第二个:

您会注意到元数据是在导出时完成的MetricA,而不是继承的导出.如果我加了进一步的出口,可以说[Export("test")]来MetricA,你的另一个出口的定义,与相同的元数据的项目MetricName和MetricDescription一个名为"测试"的合同.这表明,在分析类型时,将标识export属性,并且创建的导出定义包括在抽象树中的同一级别指定的元数据.
做你想做的最简单的方法是退出InheritedExport,并修改你的定义MetricAttribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false), MetadataAttribute]
public class MetricAttribute : ExportAttribute, IMetricAttribute
{
public MetricAttribute(string name, string description)
: base(typeof(IMetric))
{
this.MetricName = name;
this.MetricDescription = description;
}
public string MetricName { get; private set; }
public string MetricDescription { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
然后你传入typeof(IMetric)基础ExportAttribute构造函数.然后你正确地得到两个出口GetExports<IMetric>()和GetExports<IMetric, IMetricAttribute>().