MEF学习笔记(3):声明导出

声明导出

组成部件通过[System.ComponentModel.Composition.ExportAttribute]特性声明导出。在MEF有几种不同方法去声明导出,包括部件级别和通过属性和方法。

组成部件导出

当一个部件需要导出自身时一个组成部件级别的导出经常用。为了让部件导出自己,简单的方法是用[System.ComponentModel.Composition.ExportAttribute]特性修饰一个组成部件,正如下面所示一样:

[Export]
public class SomeComposablePart {
  ...
}

属性导出

部件也可以导出属性。属性导出有下面几个优点:

  • 他们允许导出密封类型例如核心CLR类型,或者其它第三方类型。
  • 他们允许从怎样创建导出中解耦导出。例如导出运行环境为你创建的现有的HttpContext。
  • 他们允许有导出同一个组成部件关系的成员,例如一个DefaultSendersRegistry组成部件导出一个sender默认设置作为属性。

举例你有一个Configuration类要导出一个整形”Timeout"契约,正如下面代码一样:

  public class Configuration
  {
    [Export("Timeout")]
    public int Timeout
    {
      get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
    }
  }
  [Export]
  public class UsesTimeout
  {
    [Import("Timeout")]
    public int Timeout { get; set; }
  }


方法导出

方法导出是部件导出它的一个方法。方法被作为委托导出,它在导出契约中被指定。方法导出有下面几个好处:

  • 他们允许好的细致控件作为导出。例如,一个规则引擎要导入一个插入式设置的方法导出。
  • 他们从任务知识的类型串保护调用者。
  • 他们可以通过轻量的代码情报中产生,你不能用其它导出做得到。

注意:由于framework的局限性,方法导出不可以超过4参数。

在下面的例子里,MessageSender类导出它的Send方法作为Action<string>委托。Processor导入相同的委托。

  public class MessageSender
  {
    [Export(typeof(Action<string>))]
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

  [Export]
  public class Processor
  {
    [Import(typeof(Action<string>))]
    public Action<string> MessageSender { get; set; }

    public void Send()
    {
      MessageSender("Processed");
    }
  }

你也可以通过使用一个简单的字符串契约导出和导入方法。例如下面所用的“Sender"契约

  public class MessageSender
  {
    [Export("MessageSender")]
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

  [Export]
  public class Processor
  {
    [Import("MessageSender")]
    public Action<string> MessageSender { get; set; }

    public void Send()
    {
      MessageSender("Processed");
    }
  }

注意:当用方法导出时,你需要提供一个类型或者一个字符串契约名,并且不能留空。

继承导出

MEF支持基类/基接口去定义导出的功能,这样它就可以被继承。这是综合遗产框架的目标,它利用MEF去发现但不需要修改现存的自定义代码。为了提供这个功能,使用System.ComponentModel.Composition.InheritedExportAttribute.例如下面的ILogger有一个InheritedExport。Logger继承ILogger所以它自动导出ILogger。

[InheritedExport]
public interface ILogger {
  void Log(string message);
}

public class Logger : ILogger {
  public void Log(string message);
}


发现非公共的组成部件

MEF支持发现公共和非公共的部件。你不需要去做任何事就能实现这个行为。请注意在中间/部份信任环境(包括Silverlight)非公有组成不被支持。

posted @ 2012-04-24 15:34  王春明  阅读(1337)  评论(0编辑  收藏  举报