如果导出的类具有关联的元数据视图,是否可以将相同的元数据视图多次导出到单个元数据对象中?下面是我想要这样做的一个例子,即导出的元数据是多个字符串列表,这在逻辑上更有意义作为多个属性:
[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;
}
答案 0 :(得分:0)
我通过使用自定义元数据视图将ExportHandledNamespaceAttribute
分割为Export
上的INamespaceHandler
和命名空间标识符上的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
}
}