• MEF学习系列笔记系列(1)


      最近,年底项目开始有点空闲,跟我们对接接口的那边正在开发,而我们这边开发完毕,但是对方接口不稳定而且很不成熟,所以暂时停止对接,等稳定再进行对接,本日在对接接口方面经验比较足,所以敢于拿出时间去学习新的知识,觉得MEF以前没怎么接触,最近想提升一下,所以就写呢这篇文章,供大家学习,由于这方面经验有限,有什么不足,望大家指出,我的Email为:wangyonghua_net@126.com.

      MEF参考资料主要来源:   

         王春明- http://www.cnblogs.com/wangchunming/archive/2012/04/23/2467128.html,

          一个人在北京- http://www.cnblogs.com/content/archive/2013/05/31/3111156.html

         以前觉得自己懂就可以啦,没有做像样的总结,给大家分享,现在我觉得写博客也要认真的对待,把实际遇到的问题,自己的理解分享给大家,望与大家交流,相互学习.

         应用程序里托管MEF

         应用程序里托管MEF包括创建一个CompositionContainer实例,添加组成部件,包括宿主本身,然后组合。

         下面是组合的步骤:

         创建一个宿主类,下面的例子里我们使用控制台应用程序,所以宿主是Program类。

            添加System.ComponentModel.Composition的引用;

            在头部添加using System.ComponentModel.Composition;

            添加一个Compose()方法,用来创建一个container实例,并跟宿主组合;

            添加一个Run()方法,用来执行Compose();

            在Main()里实例化宿主类。

            注意:对于ASP.NET和WPF应用程序,宿主类在运行时就已经实例化,所以这个步骤没有必要。

     1 using System.ComponentModel.Composition;  
     2 using System.ComponentModel.Composition.Hosting;  
     3 using System.Reflection;  
     4 using System;  
     5   
     6 public class Program  
     7 {  
     8   public static void Main(string[] args)  
     9   {  
    10      Program p = new Program();  
    11      p.Run();  
    12   }  
    13   public void Run()  
    14   {  
    15      Compose();  
    16   }  
    17   private void Compose()  
    18   {  
    19      var container = new CompositionContainer();  
    20      container.ComposeParts(this);  
    21   }  
    22 }
    View Code

    定义一个或多个导出(Export)用于给宿主导入(Import)。下面的代码,我们会定义一个IMessageSender接口,我们还会定义一个EmailSender组合部件,用来导出一个IMessageSender,这得通过声明 [System.ComponentModel.Composition.Export] 属性来实现:

     1 public interface IMessageSender  
     2   {  
     3     void Send(string message);  
     4   }  
     5   
     6   [Export(typeof(IMessageSender))]  
     7   public class EmailSender : IMessageSender  
     8   {  
     9     public void Send(string message)  
    10     {  
    11       Console.WriteLine(message);  
    12     }  
    13   }  
    View Code

    通过使用[System.ComponentModel.Composition.Import]修饰的属性,使每个导入将特性添加到宿主类。下面的例子是一个IMessageSender的导入将特性添加给Program类:

    1 [Import]  
    2 public IMessageSender MessageSender { get; set; }  
    View Code

    给容器添加部件。在MEF有几个方法可以做到这个。一个方法是直接添加目前的组成部件实例,另一个更常用的方法是通过使用目录,这个我们在下面的章节会提到.

    直接添加部件到容器
    在Compose()方法里通过重载方法ComposeParts()手动添加每个组成部件。下面的例子里一个EmailSender的实例和当前要导入的Program实例一起添加到容器。

    1 private void Compose()  
    2 {  
    3   var container = new CompositionContainer();  
    4   container.ComposeParts(this, new EmailSender());  
    5 }  
    View Code

    用数据集目录(AssemblyCatalog)添加到容器(container)
    通过使用这个目录,container句柄会自动添加部件,而不是显式的添加。为了实现这个,在Compose()里创建一个目录catalog。然后从目录创建一个解析器,把它传给container的构造函。
    下面的例子是一个用正在执行的程序集创建的AssemblyCatalog传进构造函数。我们没有添加EmailSender实例因为它会在当前程序集的目录被发现。

    1 private void Compose()  
    2   {  
    3     var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());  
    4     var container = new CompositionContainer(catalog);  
    5     container.ComposeParts(this);  
    6   }  
    View Code

    Assembly.GetExecutingAssembly()Gets the assembly that contains the code that is currently executing.
    经过上面的步骤之后,代码应该是这样:

     1 using System.ComponentModel.Composition;  
     2   using System.ComponentModel.Composition.Hosting;  
     3   using System.Reflection;  
     4   using System;  
     5   
     6   public class Program  
     7   {  
     8     [Import]  
     9     public IMessageSender MessageSender { get; set; }  
    10   
    11     public static void Main(string[] args)  
    12     {  
    13       Program p = new Program();  
    14       p.Run();  
    15     }  
    16   
    17     public void Run()  
    18     {  
    19       Compose();  
    20       MessageSender.Send("Message Sent");  
    21     }  
    22   
    23     private void Compose()  
    24     {  
    25       AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());  
    26       var container = new CompositionContainer(catalog);  
    27       container.ComposeParts(this);  
    28     }  
    29   }  
    30   
    31   public interface IMessageSender  
    32   {  
    33     void Send(string message);  
    34   }  
    35   
    36   [Export(typeof(IMessageSender))]  
    37   public class EmailSender : IMessageSender  
    38   {  
    39     public void Send(string message)  
    40     {  
    41       Console.WriteLine(message);  
    42     }  
    43   }  
    View Code

    执行上面的代码,应用程序会用它的IMessageSender导入来组装,之后Send()会被执行,结果会输出“Message Sent”

    同时我也做呢另外一个控制台项目,宿主代码代码如下:

     1 class Program  
     2    {  
     3        [ImportMany]  
     4        public ILogger[] Loggers { get; set; }  
     5   
     6        /// <summary>  
     7        ///下面的代码说明如何启动在MEF组成过程。  
     8        ///下面的步骤用于静态构造函数:   
     9        ///创建目录 (告诉MEF寻找部件 )   
    10        ///创建容器 (主机),并交给目录 。   
    11        ///容器调用Compose方法。   
    12        ///最后一步是从容器中获得logger  
    13        /// </summary>  
    14        /// <param name="args"></param>  
    15        static void Main(string[] args)  
    16        {  
    17            var p = new Program();  
    18            var assemblyCatalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());  
    19            var container = new CompositionContainer(assemblyCatalog);  
    20            container.ComposeParts(p);  
    21   
    22            foreach (var logger in p.Loggers)  
    23            {  
    24                logger.Write("写日志");  
    25            }  
    26            Console.Read();  
    27        }  
    28    }  
    View Code

    部件与契约:

    1 public interface ILogger
    2     {
    3         void Write(string message);
    4     }
    View Code
     1 /// <summary>  
     2    /// 下面的代码是使用导出属性的部分装饰  
     3    ///要求为ILogger契约。  
     4    /// </summary>  
     5    [Export(typeof(ILogger))]  
     6    public class ConsoleLogger : ILogger  
     7    {  
     8        void ILogger.Write(string message)  
     9        {  
    10            Console.WriteLine(message);  
    11        }  
    12    }  
    13   
    14    [Export(typeof(ILogger))]  
    15    public class DebugLogger : ILogger  
    16    {  
    17        void ILogger.Write(string message)  
    18        {  
    19            Debug.WriteLine(message);  
    20        }  
    21    }  
    22   
    23    [Export(typeof(ILogger))]  
    24    public class EventLogLogger : ILogger  
    25    {  
    26        void ILogger.Write(string message)  
    27        {  
    28            EventLog.WriteEntry("MEFSample", message);  
    29        }  
    30    }  
    View Code

    结果运行如下:

  • 相关阅读:
    Hello World
    函数
    js基础
    html
    npm
    数据库
    前端了解的简要php
    模块
    scrapy爬虫
    php升级代码检查
  • 原文地址:https://www.cnblogs.com/wangyhua/p/wangyonghua_net.html
Copyright © 2020-2023  润新知