c# - 如何使用 MEF Inherited Export & MetaData?

标签 c# .net c#-4.0 mef

我有一个界面:

[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 定义了两个导出。 .这是第一个及其元数据:

enter image description here

这是第二个:

enter image description here

您会注意到元数据是在 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/

相关文章:

c# - 为什么 structuremap 没有选择我的 HomeController?

c# - 将转换器从 dll 导入 XAML

c# - 使用 Web 代理的 HttpWebRequest 工作,然后在一段时间后失败

c# - 在不使用 BigInt 的情况下计算 2^1000 的总和

c#-4.0 - 动态CRM插件下载Word文档

c# - 开始将 Redis 与 ASP.NET 结合使用

c# - 如何处理System.Data.Entity.Validation.DbEntityValidationException?

c# - 'yield return' 返回什么具体类型?

c# - AutoMapper 中相同实体类型的不同映射规则

asp.net - C# - 一次向 AS400 插入多条记录