首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在同一个类上多次导出相同的元数据

如何在同一个类上多次导出相同的元数据
EN

Stack Overflow用户
提问于 2018-03-08 01:00:29
回答 1查看 86关注 0票数 0

给定一个具有关联元数据视图的导出类,是否可以多次将相同的元数据视图导出到一个有效的元数据对象中?下面是我为什么要这样做的一个示例,即要导出的元数据是多个字符串列表,这在逻辑上作为多个属性更有意义:

代码语言:javascript
运行
复制
[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
    }
}

这就是我想要使用这种导出的方式:

代码语言:javascript
运行
复制
public void ExampleUsageMethod() 
{
    var handler = mefContainer.GetExports<INamespaceHandler, INamespaceHandlerMetadata>().First();
    string[] handledNamespaces = handler.Metadata.HandledNamespaces;
}
EN

Stack Overflow用户

发布于 2018-03-08 22:47:22

我通过使用定制的元数据视图将ExportHandledNamespaceAttribute拆分成INamespaceHandler上的单个Export和名称空间标识符上的MetadataAttribute,从而解决了这个问题,如下所示。这里的技巧是让INamespaceHandlerMetadata期望的导入和HandlesNamespaceAttribute提供的导出之间的契约完全正确。如果我可以改进/澄清这个答案,请告诉我:

代码语言:javascript
运行
复制
[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的示例用例

代码语言:javascript
运行
复制
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
    }
}
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49157431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档