20

MEF 允许您通过使用ImportMany属性导入多个部件。它如何确定检索相关导出并将它们添加到您正在填充的枚举中的顺序?例如,我将如何导入必须以特定顺序触发的多个 IRule?我能想到的唯一方法是在 IRule 中有一个 OrderValue 属性并手动排序:

public class Engine
{
  [ImportMany]
  public IEnumerable<IRule> Rules { get; set; }

  public void Run()
  {
    // ...
    // Initialise MEF
    // ...

    //
    // Do I need to manually order Rules here?
    //

    foreach (IRule rule in Rules)
    {
      // Must execute in a specific order
      rule.Execute();
    }
  }
}
4

3 回答 3

31

默认情况下,MEF 不保证导入的导出的任何顺序。但是在 MEF 中,您可以通过使用一些元数据和自定义集合来进行一些排序。例如,您可以执行以下操作:

public interface IRule { }

[Export(typeof(IRule))]
[ExportMetadata("Order", 1)]
public class Rule1 : IRule { }

[Export(typeof(IRule))]
[ExportMetadata("Order", 2)]
public class Rule2 : IRule { }

public interface IOrderMetadata
{
    [DefaultValue(Int32.MaxValue)]
    int Order { get; }
}

public class Engine
{
    public Engine()
    {
        Rules = new OrderingCollection<IRule, IOrderMetadata>(
                           lazyRule => lazyRule.Metadata.Order);
    }

    [ImportMany]
    public OrderingCollection<IRule, IOrderMetadata> Rules { get; set; }
}

然后,您将拥有一组按元数据排序的规则。您可以在http://codepaste.net/ktdgoh找到 OrderingCollection 示例。

于 2009-11-20T18:54:47.377 回答
6

在 MEF 中实现这种排序的最佳方式是利用我们的元数据工具。您可以将自己的元数据附加到可用于排序和过滤的导出中。元数据还允许您延迟部件的实例化,直到实际需要它们。此外,您可以创建自定义导出属性,这些属性提供了一种提供元数据的简洁方式。

检查此链接以获取有关如何定义元数据和自定义导出的信息:链接文本

您还可以在我们的 MEF 论坛上发现此主题很有用。您将在其中找到有关 AdaptingCollection 方法的讨论,该方法允许您使用应用元数据过滤器/顺序的自定义集合。

HTH格伦

于 2009-11-20T18:56:02.820 回答
1

您可以让规则按顺序相互导入(使用装饰器模式),但是每个规则都需要了解它之前的特定规则,这可能不是您想要的。

MEF 可以帮助您发现零件,之后您如何处理它们取决于您。如果您想对零件进行分类,那就继续吧,这没有错!

于 2009-11-20T13:32:07.693 回答