给定一个具有关联元数据视图的导出类,是否可以多次将相同的元数据视图导出到一个有效的元数据对象中?下面是我为什么要这样做的一个示例,即要导出的元数据是多个字符串列表,这在逻辑上作为多个属性更有意义:
[ExportHandledNamespace("System", "Data")]
[ExportHandledNamespace("System", "Core")]
public class NamespaceHandler : INamespaceHandler { }
public interface INamespaceHandlerMetadata
{
string[] HandledNamespaces { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class ExportHandledNamespaceAttribute : ExportAttribute, INamespaceHandlerMetadata
{
// In my use case, NamespaceHandler would be in a plugin assembly
// and I don't want them using this delimiter themselves
private string _namespaceDelimiter = ".";
public string[] HandledNamespaces { get; }
public ExportHandledNamespaceAttribute(params string[] namespaceIdentifiers)
: base(typeof(INamespaceHandler))
{
string namespace = String.Join(_namespaceDelimiter, namespaceIdentifiers);
// Somehow add this to an existing metadata view's HandledNamespaces
}
}这就是我想要使用这种导出的方式:
public void ExampleUsageMethod()
{
var handler = mefContainer.GetExports<INamespaceHandler, INamespaceHandlerMetadata>().First();
string[] handledNamespaces = handler.Metadata.HandledNamespaces;
}发布于 2018-03-08 22:47:22
我通过使用定制的元数据视图将ExportHandledNamespaceAttribute拆分成INamespaceHandler上的单个Export和名称空间标识符上的MetadataAttribute,从而解决了这个问题,如下所示。这里的技巧是让INamespaceHandlerMetadata期望的导入和HandlesNamespaceAttribute提供的导出之间的契约完全正确。如果我可以改进/澄清这个答案,请告诉我:
[Export(typeof(INamespaceHandler))]
[HandlesNamespace("System", "Data")]
[HandlesNamespace("System", "Core")]
public class NamespaceHandler : INamespaceHandler { }
[MetadataViewImplementation(typeof(NamespaceHandlerMetadata))]
public interface INamespaceHandlerMetadata
{
string[] HandledNamespaces { get; set; }
}
public class NamespaceHandlerMetadata : INamespaceHandlerMetadata
{
string[] HandledNamespaces { get; set; }
public NamespaceHandlerMetadata(IDictionary<string, object> exportedMetadata)
{
HandledNamespaces = exportedMetadata[nameof(HandledNamespaces)];
}
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class HandlesNamespaceAttribute : Attribute
{
private string _namespaceDelimiter = ".";
// Because the attribute is marked AllowMultiple = true, this will get exported
// as a string[], despite it appearing to only be set once in the constructor below
public string HandledNamespaces { get; }
public ExportHandledNamespaceAttribute(params string[] namespaceIdentifiers)
: base(typeof(INamespaceHandler))
{
string namespace = String.Join(_namespaceDelimiter, namespaceIdentifiers);
HandledNamespaces = namespace;
}
}示例用法与问题中的相同,即查询Lazy<INamespaceHandler, INamespaceHandlerMetadata>的导出并获取其HandledNamespaces。但下面是另一个使用ImportMany的示例用例
public class NamespaceHandlerManager, IPartImportsSatisfiedNotification
{
[ImportMany]
public IEnumerable<Lazy<INamespaceHandler, INamespaceHandlerMetadata>> NamespaceHandlers { get; set; }
public NamespaceHandlerManager() { }
public void OnImportsSatisfied()
{
// NamespaceHandlers will be populated with the exports from any
// loaded assemblies by this point, do what you want with it
}
}https://stackoverflow.com/questions/49157431
复制相似问题