metadata - 来自导出部件的 MEF 元数据

标签 metadata mef

我正在寻找将 MEF 用于我正在构建的应用程序的插件系统。我希望每个组件在(GUID)上都有一个我希望能够查找的标识符。但是,此 ID 在处理导出部件时也很有用。

有没有一种方法可以让我在导出的部分上拥有一个包含 ID 和属性(或方法)的 Metadata 属性,而不是让开发人员填写它两次或使用反射从属性中找到它?

最佳答案

它可能是 MEF 元数据属性和抽象基类的混合体。我会将我的插件契约(Contract)定义为:

public interface IPluginMetadata
{
  Guid PluginId { get; }
}

public interface IPlugin : IPluginMetadata
{
  void Initialise();
}

我已经强制 IPlugin接口(interface)也继承了我们的元数据合约IPluginMetadata .接下来,我们可以创建一个自定义导出属性:
[AttributeUsage(AttributeTargets.Class, Inherit = true), MetadataAttribute]
public class ExportPluginAttribute : ExportAttribute, IPluginMetadata
{
  public ExportPluginAttribute(string pluginId) : base(typeof(IPlugin))
  {
    if (string.IsNullOrEmpty(pluginId))
      throw new ArgumentException("'pluginId' is required.", "pluginId");

    PluginId = new Guid(pluginId);
  }

  public Guid PluginId { get; private set; }
}

您无需使用元数据协定 IPluginMetadata 装饰导出属性,因为 MEF 无论如何都会投影属性,但我更喜欢这样做,所以如果我确实对我的元数据契约(Contract)进行了更改,那么我的导出属性也应该更新。没有伤害,没有犯规。

完成此操作后,我们可以定义一个抽象基类来实现我们的插件契约:
public abstract class PluginBase : IPlugin
{
  protected PluginBase()
  {
    var attr = GetType()
      .GetCustomAttributes(typeof(ExportPluginAttribute), true)
      .Cast<ExportPluginAttribute>()
      .SingleOrDefault();

    PluginId = (attr == null) ? Guid.Empty : attr.PluginId;
  }

  public virtual Guid PluginId { get; private set; }

  public abstract void Initialise();
}

然后我们可以通过抽象类的构造函数获取自定义属性,并相应地应用属性。我们可以这样做:
public IPlugin GetPlugin(Guid id)
{
  var plugin = container
    .GetExports<IPlugin, IPluginMetadata>()
    .Where(p => p.Metadata.PluginId == id)
    .Select(p => p.Value)
    .FirstOrDefault();

  return plugin;
}

并且:
[ExportPlugin("BE112EA1-1AA1-4B92-934A-9EA8B90D622C")]
public class MyPlugin : PluginBase
{
  public override Initialise()
  {
    Console.WriteLine(PluginId);
  }
}

我们可以看到 PluginId通过导出的元数据以及我们插件的属性公开。

该代码都未经测试,但我希望它能将您推向正确的方向。

关于metadata - 来自导出部件的 MEF 元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4237532/

相关文章:

wpf - PRISM + MEF + MVVM——不确定从哪里开始?

.net - MEF 和 Unity 之间以及用途有何不同?

c# - Mef2 在每个模块中配置注册

mysql - 查询MYSQL post_meta到新格式的表

wordpress - 如何根据 TERM 元键获取术语和帖子?

c++ - TagLib: 无法打开文件

java - 如何使用 apache fop 将自定义属性元数据添加到 pdf

c++ - 我正在尝试获取媒体播放器的元数据,但在 QT 中不断出现 C2228 错误

c# - MEF 4.5 中缺少 CompositionInitializer。我可以用什么代替?

C# MEF 不能做类型绑定(bind)?