Впервые я увидел такое поведение, но насколько я понимаю, метаданные генерируются для каждого экспорта на уровне типа. Итак, учитывая:
[Metric("MetricA", "MetricA")]
public class MetricA : IMetric
{
}
У вас есть два экспорта для этого типа. У вас есть экспорт MetricA
, который косвенно предоставляется вашим MetricAttribute
, и у вас есть унаследованный экспорт для IMetric
, предоставленный атрибутом InheritedExport(typeof(IMetric))
в вашем интерфейсе.
Если вы посмотрите на контейнер, вы увидите два экспорта, определенных для MetricA
. Вот первое, с его метаданными:
А вот и второе:
Вы заметите, что метаданные создаются при экспорте MetricA
, а не унаследованном экспорте. Если я добавил дополнительный экспорт, скажем, от [Export("test")]
до MetricA
, вы получите другое определение экспорта с теми же элементами метаданных для MetricName
и MetricDescription
для контракта с именем «test». Это показывает, что при анализе типа атрибут экспорта идентифицируется, а созданное определение экспорта включает метаданные, указанные на том же уровне в дереве абстракции.
Самый простой способ сделать то, что вы хотите, это исключить 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>()
.