我有一个界面:
[InheritedExport(typeof(IMetric))]
public interface IMetric { ... }
我有一个元属性接口(interface):
public interface IMetricAttribute { ... }
以及实现它的属性:
[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;
}
}
然后我有两个类:
[Metric("MetricA","MetricA")]
public class MetricA: IMetric { ... }
[Export(typeof(IMetric))] <<<< THIS IS IMPORTANT
[Metric("MetricB", "MetricB")]
public class MetricB: IMetric { ... }
然后我尝试导入指标(我可以在目录中看到两者)
后面返回的是MetricA AND MetricB
var metrics = compositionContainer.GetExports<IMetric>();
然而,以下仅返回 MetricB 而不是 MetricA
var metrics = compositionContainer.GetExports<IMetric, IMetricAttribute>();
知道为什么吗?
(注意 MetricB 上的重复导出(它已经从实现 IMetric 中获得))
谢谢
大卫
最佳答案
我第一次看到这种行为,但据我所知,元数据是在类型级别的每次导出生成的。所以,给定:
[Metric("MetricA", "MetricA")]
public class MetricA : IMetric
{
}
您有两个针对此类型的导出。您导出了 MetricA
这是由您隐含提供的 MetricAttribute
,并且您拥有 IMetric
的继承导出由 InheritedExport(typeof(IMetric))
提供界面上的属性。
如果您查看容器,您会注意到为 MetricA
定义了两个导出。 .这是第一个及其元数据:
这是第二个:
您会注意到元数据是在 MetricA
的导出时完成的,而不是继承的导出。如果我添加了进一步的导出,可以说 [Export("test")]
至 MetricA
,您将获得另一个导出定义,其中元数据项与 MetricName
相同和 MetricDescription
对于名为“测试”的契约(Contract)。这向您表明,随着类型的分析,导出属性被识别,并且创建的导出定义包括在抽象树中相同级别指定的元数据。
做你想做的最简单的方法是去掉 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; }
}
然后你在哪里传递 typeof(IMetric)
到基地ExportAttribute
构造函数。然后您正确地获得了 GetExports<IMetric>()
的两个导出。和 GetExports<IMetric, IMetricAttribute>()
.
关于c# - 如何使用 MEF Inherited Export & MetaData?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6570930/