2012-12-12 36 views
2

美好的一天,请你帮助我完成这项复杂的任务。 我使用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 

对于每个模块有一组在IArmModule,通过Dictionary<string, Settings.ParamDescriptor> CreateSettingsBlock()方法生成的属性,其中键包含的属性代码和值包含奇特名称和默认值。

我主要的应用程序,我使用Lazy<T, TMetadata>对该办法,Lazy<T, TMetadata>将为recieving设置从方法阻止创建IArmTaskModule实例导入模块这样

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

的问题。 我想通过向元数据添加属性信息来阻止它。我试图扩大与新名单()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, 

有没有人有任何建议?

回答

2

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序列时,只有在检查了Metadata属性并确保当前模块是您想要的模块后,才会访问Value属性。然后你访问Value属性,模块将被创建。

+0

谢谢你的回答。有关命名约定和自定义属性类准则的提示和链接非常有用。但你根本不回答我的问题。嗯..我会尝试重复它简短的方式:我怎么能通过元数据通过收集自定义对象(在我的情况下它是IArmModuleProperty的集合)? – xakz

+0

@xakz你是什么意思传递自定义对象的集合。每个导入都会有一个元数据实例。您可以将属性添加到元数据类。而不是描述符属性,您可以添加其他属性。请注意,这是元数据。它应该可以帮助你过滤进口。你有什么想法?你在问题中的价值财产是什么? –