2

美好的一天,请您协助我完成这项复杂的任务。我用 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()in 方法生成的属性IArmModule,其中 Key 包含属性代码,Value 包含花哨的名称和默认值。

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

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

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

[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, 

有没有人有什么建议?

4

1 回答 1

1

该类ModuleMetadata不遵循自定义导出属性准则

它应该是这样的:

    [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属性并创建模块。

于 2012-12-12T16:13:44.413 回答