MEF如何确定其进口的顺序?

时间:2009-11-20 13:01:36

标签: c# mef

MEF允许您通过使用ImportMany属性导入多个部分。它如何确定检索相关导出的顺序并将它们添加到您正在填充的可枚举中?例如,如何导入必须以特定顺序触发的多个IRules?我能想到的唯一方法是在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();
    }
  }
}

3 个答案:

答案 0 :(得分:30)

默认情况下,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示例。

答案 1 :(得分:6)

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

请查看此链接,了解有关如何定义元数据和自定义导出的信息:link text

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

HTH 格伦

答案 2 :(得分:1)

你可以让规则按顺序相互导入(使用Decorator模式),但是每个规则都需要知道它之前的特定规则,这可能不是你想要的。

MEF可以帮助您发现部件,之后您使用它们取决于您。如果您想对零件进行分类,那么请继续,这没有任何问题!