美好的一天,你能帮我完成这个复杂的任务吗? 我用 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
的实例用于从方法接收设置 block 。 我想通过向元数据添加属性信息来防止它。我试图用 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,
有人有什么建议吗?
最佳答案
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);
}
}
你的元数据接口(interface)是这样的:
public interface IArmModuleMetadata
{
ModuleDescriptor Descriptor { get; }
}
注意:
- 您不必让您的自定义导出属性实现元数据接口(interface)。 MEF 将处理此事。
- 您需要将导出的类型传递给 ExportAttribute 的构造函数。
- 您将自定义导出属性的所有公共(public)属性添加到界面。
我还更改了自定义属性类的名称,以符合创建自定义属性的指南(我现在找不到这方面的来源,但您可以查看 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
属性并创建模块。
关于c# - 导出多个 MEF 元数据属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13842360/