MEF元数据与价值

时间:2014-02-20 06:18:29

标签: c# metadata mef

我在这里是一个完全的初学者,所以这可能是一个非常明显的问题,我似乎无法理解或找到答案。我已经阅读了MSDN example,其中大部分都是完全合理的。

在示例中,它们定义了以下接口并提供了这样的示例用法;

public interface IOperation
{
    int Operate(int left, int right);
}

public interface IOperationData
{
    char Symbol { get; }
}

[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '+')]
public class Add : IOperation
{
    public int Operate(int left, int right)
    {
        return left + right;
    }
}

我想我必须在这里误解一些事情。

  • IOperationDataExportMetadata有什么意义?
  • 为什么我不能同时删除它们并将char Symbol {get;}添加到IOperation

然后我可以使用Add.Value.Symbol代替Add.Metadata.Smybol。我想这并不是一个巨大的改变,但它确实意味着我不需要ExportMetadataValueMetadata之间有什么区别?为什么示例会像它一样使用它们?属性为Metadata,方法为Value?它似乎没有很好地解释给我。

1 个答案:

答案 0 :(得分:2)

MEF允许可组合部件提供元数据。这里的元数据是一组静态已知的属性,对于部分类型而言是典型的,而不是类型实例

假设您在给定示例中为计算器构建GUI 每个操作都是一个插件,通过MEF容器加载。在用户选择之前,您不希望实例化每个插件,但是您希望使用按钮构建面板,其中每个按钮都包含操作符号。

这就是您需要使用元数据而不是将char Symbol {get;}添加到IOperation的原因:

  • 您可以在不实例化部分的情况下访问元数据(这可能很昂贵);
  • 元数据属于可组合部分,该部分的每个实例应该具有相同的元数据(尽管计算器示例不是理解该事实的好选择)。

您正在描述元数据接口IOperationData并将ExportMetadata属性应用于可组合部件定义。然后,在运行时,MEF查看Add类,并动态构建IOperationData实现。使用ExportMetadata中提供的值初始化该实现的实例。最后,您可以稍后在主机应用程序中使用IOperationData访问Add.Metadata.Smybol实施的值。

<强>更新即可。 ExportMetadata允许您添加多个元数据值,但使用自定义属性添加元数据通常更方便,该属性继承自ExportAttribute

public interface IMyPlugin {}
public interface IMyMetadata
{
    int Value1 { get; }
    string Value2 { get; }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MyExportAttribute : ExportAttribute, IMyMetadata
{
    public MyExportAttribute(int value1, string value2)
        : base(typeof(IMyPlugin))
    {
        Value1 = value1;
        Value2 = value2;
    }

    public int Value1 { get; private set; }
    public string Value2 { get; private set; }
}

用法:

   [MyExport(1, "Orange")] 
   public class MyPlugin : IMyPlugin {}