导出多个MEF元数据属性

时间:2012-12-12 14:55:09

标签: c# metadata mef

美好的一天,能帮助我完成这项复杂的工作。 我用MEF开发模块应用程序。每个模块都有这样的元数据:

    [MetadataAttribute]
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
        public abstract class ModuleMetadata : ExportAttribute, IArmModuleMetadata
        {
            private ModuleDescriptor _descriptor;

            public ModuleMetadata(string name, string code, string category, string iconUri)
                : base()
            {
                _descriptor = new ModuleDescriptor(name, code, category, iconUri);               
     }
}

我这样用:

 [Export(typeof(IArmTaskModule))]
[TaskModuleMetadata("test1", "code",
     @"pack://application:,,,/WpfVisualModule;component/Icons/chart_line_error.png",
     "road_weather_stations",
     TargetItem = TargetItems.ControlComplex)]
class AdvancedChartContract : Burstroy.Arm.Contracts.IArmTaskModule

对于每个模块,Dictionary<string, Settings.ParamDescriptor> CreateSettingsBlock()中的IArmModule方法生成一组属性,其中Key包含属性代码,Value包含花哨名称和默认值。

在我的主应用程序中,我使用Lazy<T, TMetadata>导入像这样的模块

[ImportMany(typeof(IArmTaskModule), AllowRecomposition = true)]
private IEnumerable<Lazy<IArmTaskModule, IArmTaskModuleMetadata>> _taskModules;

此方法中的问题Lazy<T, TMetadata>将创建IArmTaskModule的实例,以便从方法中接收设置块。 我想通过向元数据添加属性信息来阻止它。我尝试使用新的List()扩展attrribute构造函数,但它失败了(属性限制), 我也尝试制作新的属性

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ExportedParam : ExportAttribute, IArmModuleProperty
{
    public ExportedParam(string code, string fancyName) 
        : base()
    {
        this.Code = code;
        this.FancyName = fancyName;
        //this.Value = value;
    }

    public string Code { get; private set; }
    public string FancyName { get; private set; }
    public object Value { get; private set; }
}

但它也失败了。

[ExportedParam("a", "b")]
[ExportedParam("b", "c")]
[ExportMetadata("fffffuuu", 2)]
class MeteoSummary : IArmVisualModule, 

有人有任何建议吗?

1 个答案:

答案 0 :(得分:1)

ModuleMetadata课程不遵循custom export attribute guidelines

应该是这样的:

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public abstract class ModuleMetadataExportAttribute : ExportAttribute
    {
        public ModuleDescriptor Descriptor { get; private set; }

        public ModuleMetadata(string name, string code, string category, string iconUri)
            : base(typeof(IArmTaskModule))
        {
            Descriptor= new ModuleDescriptor(name, code, category, iconUri);               
        }
     }

您的元数据界面如下:

public interface IArmModuleMetadata
{
    ModuleDescriptor Descriptor { get; }
}

请注意:

  • 您不必使自定义导出属性实现元数据接口。 MEF将处理这个问题。
  • 您需要将导出的类型传递给ExportAttribute的构造函数。
  • 将自定义导出属性的所有公共属性添加到接口。

我还更改了自定义属性类的名称,以符合创建自定义属性的指导原则(我现在找不到此源,但您可以查看Cwalina,Abrams的第2版框架设计指南)。但这不是必要的。

然后你这样导出:

[ModuleMetadataExport(...))] //Add your params here.
[TaskModuleMetadata("test1", "code",
     @"pack://application:,,,/WpfVisualModule;component/Icons/chart_line_error.png",
     "road_weather_stations",
     TargetItem = TargetItems.ControlComplex)]
class AdvancedChartContract : Burstroy.Arm.Contracts.IArmTaskModule

我离开了TaskModuleMetadata,因为我不知道它是什么。我认为它与MEF没有关系。

最后确保导入部分保持不变。然后,当您遍历_taskModules序列时,只有在检查了Value属性并确保当前模块是您想要的模块后,才会访问Metadata属性。然后,您访问Value属性,将创建模块。