码迷,mamicode.com
首页 > 其他好文 > 详细

MEF系列一 : MEF简介及解决什么问题

时间:2015-12-14 18:43:15      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:

首先,什么是MEF?

The Managed Extensibility Framework or MEF is a library for creating lightweight, extensible applications. It allows application developers to discover and use extensions with no configuration required. It also lets extension developers easily encapsulate code and avoid fragile hard dependencies. MEF not only allows extensions to be reused within applications, but across applications as well.

MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库。 应用程序开发人员可利用该库发现并使用扩展,而无需进行配置。 扩展开发人员还可以利用该库轻松地封装代码,避免生成脆弱的硬依赖项。 通过 MEF,不仅可以在应用程序内重用扩展,还可以在应用程序之间重用扩展。

 MSDN中是这么说哒~根据定义,可以理解,MEF首先是一个库,可以用来创建可扩展的轻型应用程序,这个也可以接受。刚开始的时候,很多地方是有疑问的。

  • 可以利用这个库发现并使用扩展,是怎么发现的?又是怎么使用的呢?
  • 无需进行配置,为什么突然说不需要配置?在这个框架出来之前,有什么样的框架是需要配置才能使用?MEF又是在什么情况下为了解决什么而出现的呢?
  • 利用这个库轻松封装代码,怎么封装?避免生成硬依赖项,怎么避免,什么是硬依赖项?
  • 可以在程序内重用扩展,也可以在程序之间重用,怎么重用?
  • 如何通信 ?

呵呵哒,好嘛,不懂。因为不懂,就想知道这个东西凭什么可以以这样的姿态出现。

以下内容转载自:为什么要MEF?

---------------------------------------------------------------------------------------------------------------------

通常,创建可重用的代码库并在程序中使用。在传统的Win32应用程序中,如果一个类库被引用至某个应用程序,连接器(Linker)在PE Header中添加此类库的引用。当运行时试图加载应用程序,加载器(Loader)将执行如下操作:

  1. 找出所有依赖项;
  2. 加载它们到内存;
  3. 映射它们到相应的指针;
  4. 启动主例程.

但在.NET环境中,中间有CLR和JIT机制,所以情况有些许不同.加载器只会加载Main方法中使用的那些类库,IL(Intermediate Language,中间语言)将Main方法中调用的其它方法在需要时即时编译(JIT)并加载到内存,这也是MEF的基础之一.

案例

下来看一个明显感觉到需要用到MEF的场景,创建一个控制台应用程序来达到此目的。

  1. 创建一个简单的控制台应用程序 “WOMEF”(Without MEF);
  2. 用如下代码替换Program.cs;
using System;
using WOMEFLib;

namespace WOMEF
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("按X键退出,否则继续.");
            ConsoleKeyInfo key = Console.ReadKey(true);
            while (key.Key != ConsoleKey.X)
            {
                new Program().Speak();
                key = Console.ReadKey(true);
            }
        }

        public void Speak()
        {
            Console.Write("Speak:");
            ISpeak s = new Speak();
            s.SayHello();
        }
    }
}


在新的类库项目中定义ISpeakSpeak:

  1. 在解决方案中添加类库项目 “WOMEFLib”;
  2. 删除Class1.cs;
  3. 添加接口ISpeak.cs;
    namespace WOMEFLib
    {
        public interface ISpeak
        {
            void SayHello();
        }
    }

     

  4. 添加接口的实现Speak.cs;
    namespace WOMEFLib
    {
        public class Speak:ISpeak
        {
            public void SayHello()
            {
                Console.WriteLine("Hello World!");
            }
        }
    }

     

在WOMEF项目中添加对WOMEFLib项目的引用,解决方案中右键WOMEF项目,属性\生成\配置,选择”Release”,保存、生成、调试,这都不是我们关注的重点,我们要关注的是这两个程序集的相关的问题。

技术分享

 

我们将要验证以下几点:

  1. 加载器何时加载WOMEFLib.dll;
  2. 当应用程序启动时缺少WOMEFLib.dll时会怎样;
  3. Program.Speak方法何时被JIT编译;
  4. 第一次等待用户输入时将WOMEFLib.dll复制到程序所在目录会如何;

要验证以上几点,我们需要在运行时查看方法列表及程序集信息,以下将围绕这几点进行阐述。

需要用到的工具,Windbg,MSIL 反汇编程序,关于这两个工具可从 这里下载安装 。

有关SOS 调试扩展的资料可参考这里

加载器何时加载WOMEFLib.dll

  1. 启动Windbg;
  2. 单击 File->Open executable,选择Release目录下WOMEF.exe,打开;
  3. Windbg 会停在断点int3处(WinDbg 会在调试目标的进程中创建一个远线程,并在这个远线程中执行 ntdll!DbgBreakPoint 函数,它会在目标进程中产生一次 int3 异常,这个异常被Windbg捕获,所以WOMEF.exe就中断到调试器中了),按F5继续;
    Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
    Copyright (c) Microsoft Corporation. All rights reserved.

    CommandLine: D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    Symbol search path is: *** Invalid ***
    ****************************************************************************
    * Symbol loading may be unreliable without a symbol search path.           *
    * Use .symfix to have the debugger choose a symbol path.                   *
    * After setting your symbol path, use .reload to refresh symbol locations. *
    ****************************************************************************
    Executable search path is:
    ModLoad: 01330000 01338000   WOMEF.exe
    ModLoad: 77570000 776ad000   ntdll.dll
    ModLoad: 71aa0000 71aea000   C:\Windows\SYSTEM32\MSCOREE.DLL
    ModLoad: 760c0000 76194000   C:\Windows\system32\KERNEL32.dll
    ModLoad: 75830000 7587a000   C:\Windows\system32\KERNELBASE.dll
    (1228.26bc): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=00000000 ecx=001af66c edx=775b6344 esi=fffffffe edi=00000000
    eip=7760ebbe esp=001af688 ebp=001af6b4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll -
    ntdll!LdrVerifyImageMatchesChecksum+0x633:
    7760ebbe cc              int     3
    0:000> g
    ModLoad: 75eb0000 75f50000   C:\Windows\system32\ADVAPI32.dll
    ModLoad: 75e00000 75eac000   C:\Windows\system32\msvcrt.dll
    ModLoad: 76010000 76029000   C:\Windows\SYSTEM32\sechost.dll
    ModLoad: 75d50000 75df1000   C:\Windows\system32\RPCRT4.dll
    ModLoad: 71a30000 71a96000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
    ModLoad: 761a0000 761f7000   C:\Windows\system32\SHLWAPI.dll
    ModLoad: 77750000 7779e000   C:\Windows\system32\GDI32.dll
    ModLoad: 75c80000 75d49000   C:\Windows\system32\USER32.dll
    ModLoad: 776b0000 776ba000   C:\Windows\system32\LPK.dll
    ModLoad: 774d0000 7756d000   C:\Windows\system32\USP10.dll
    ModLoad: 75fe0000 75fff000   C:\Windows\system32\IMM32.DLL
    ModLoad: 773b0000 7747c000   C:\Windows\system32\MSCTF.dll
    ModLoad: 6d910000 6df80000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    ModLoad: 6d7a0000 6d85e000   C:\Windows\system32\MSVCR100_CLR0400.dll
    (1228.26bc): Unknown exception - code 04242420 (first chance)
    ModLoad: 6c7d0000 6d591000   C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\b58db50e1b6b9a69014a31d72b611c30\mscorlib.ni.dll
    ModLoad: 6c5e0000 6c5f0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll
    ModLoad: 76400000 7655c000   C:\Windows\system32\ole32.dll
    ModLoad: 75640000 7564c000   C:\Windows\system32\CRYPTBASE.dll
    ModLoad: 63b80000 63be0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    ModLoad: 003a0000 003a8000   WOMEFLib.dll
    ModLoad: 004d0000 004d8000   WOMEFLib.dll
  4. 此时,程序等待用户输入,显示为"按X键退出,否则继续." ;
  5. 在Windbg窗体中,单击菜单 Debug->Break(或者按Ctrl+Break),
    (1228.2524): Break instruction exception - code 80000003 (first chance)
    eax=7ffda000 ebx=00000000 ecx=00000000 edx=7760d7eb esi=00000000 edi=00000000
    eip=775a3370 esp=012ffcd0 ebp=012ffcfc iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll!DbgBreakPoint:
    775a3370 cc              int     3
  6. 加载CLR,在Windbg命令行中输入”.loadby sos clr”  注意,由于在.NET FW 4中CLR 的dll文件更名为clr.dll,所以在.NET4中应输入”.loadby sos clr”,在.NET FW3中应输入”.loadby sos.dll mscorwks”
    0:004> .loadby sos clr
    
  7. 在Windbg命令行中输入”!dumpdomain”命令列出进程中的所有程序集;
    0:004> !dumpdomain
    *********************************************************************
    * Symbols can not be loaded because symbol path is not initialized. *
    *                                                                   *
    * The Symbol Path can be set by:                                    *
    *   using the _NT_SYMBOL_PATH environment variable.                 *
    *   using the -y <symbol_path> argument when starting the debugger. *
    *   using .sympath and .sympath+                                    *
    *********************************************************************
    PDB symbol for clr.dll not loaded
    --------------------------------------
    System Domain:      6df03478
    LowFrequencyHeap:   6df03784
    HighFrequencyHeap:  6df037d0
    StubHeap:           6df0381c
    Stage:              OPEN
    Name:               None
    --------------------------------------
    Shared Domain:      6df03140
    LowFrequencyHeap:   6df03784
    HighFrequencyHeap:  6df037d0
    StubHeap:           6df0381c
    Stage:              OPEN
    Name:               None
    Assembly:           002462e8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader:        00246388
      Module Name
    6c7d1000            C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

    --------------------------------------
    Domain 1:           00201520
    LowFrequencyHeap:   0020189c
    HighFrequencyHeap:  002018e8
    StubHeap:           00201934
    Stage:              OPEN
    SecurityDescriptor: 00202c98
    Name:               WOMEF.exe
    Assembly:           002462e8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader:        00246388
    SecurityDescriptor: 002460b8
      Module Name
    6c7d1000            C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll


    Assembly:           00253588 [D:\Test\Test\WOMEF\bin\Release\WOMEF.exe]
    ClassLoader:        00253628
    SecurityDescriptor: 00252dd8
      Module Name
    001d2e9c            D:\Test\Test\WOMEF\bin\Release\WOMEF.exe


    Assembly:           00262830 [D:\Test\Test\WOMEF\bin\Release\WOMEFLib.dll]
    ClassLoader:        002628d0
    SecurityDescriptor: 00255df8
      Module Name
    001d38d0            D:\Test\Test\WOMEF\bin\Release\WOMEFLib.dll
  8. 在应用程序域中有三个程序集被加载,分别是mscorlib.dll、WOMEF.exe、WOMEFLib.dll,见粗体字部分;
  9. 可见加载器加载了引用的程序集WOMEFLib.dll,虽然还没有使用此dll中的任何类型,此刻执行到
    ConsoleKeyInfo key = Console.ReadKey(true);
    虽然还没有使用WOMEFLib.dll中的任何东西,但依然被加载,这是为什么呢?因为WOMEFLib.dll已经在WOMEF.exe的manifest中,请先关闭Windbg。
    技术分享
  10. 启动IL,打开WOMMEF.exe;
    技术分享
  11. 双击 manifest,可以看到如下
    技术分享

当应用程序启动时缺少WOMEFLib.dll时会怎样

接下来我们测试下当缺少WOMEFLib.dll时会发生什么,将Release目录中的WOMEFLib.dll剪贴到别的地方,如桌面,

  1. 启动Windbg,File-> Open executable,打开Release目录下的WOMEF.exe,按F5继续;
    CommandLine: D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    Symbol search path is: *** Invalid ***
    ****************************************************************************
    * Symbol loading may be unreliable without a symbol search path.           *
    * Use .symfix to have the debugger choose a symbol path.                   *
    * After setting your symbol path, use .reload to refresh symbol locations. *
    ****************************************************************************
    Executable search path is: 
    ModLoad: 000e0000 000e8000   WOMEF.exe
    ModLoad: 77570000 776ad000   ntdll.dll
    ModLoad: 71aa0000 71aea000   C:\Windows\SYSTEM32\MSCOREE.DLL
    ModLoad: 760c0000 76194000   C:\Windows\system32\KERNEL32.dll
    ModLoad: 75830000 7587a000   C:\Windows\system32\KERNELBASE.dll
    (2744.ab8): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=00000000 ecx=002ff8a4 edx=775b6344 esi=fffffffe edi=00000000
    eip=7760ebbe esp=002ff8c0 ebp=002ff8ec iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
    ntdll!LdrVerifyImageMatchesChecksum+0x633:
    7760ebbe cc              int     3
    0:000> g
    ModLoad: 75eb0000 75f50000   C:\Windows\system32\ADVAPI32.dll
    ModLoad: 75e00000 75eac000   C:\Windows\system32\msvcrt.dll
    ModLoad: 76010000 76029000   C:\Windows\SYSTEM32\sechost.dll
    ModLoad: 75d50000 75df1000   C:\Windows\system32\RPCRT4.dll
    ModLoad: 71a30000 71a96000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
    ModLoad: 761a0000 761f7000   C:\Windows\system32\SHLWAPI.dll
    ModLoad: 77750000 7779e000   C:\Windows\system32\GDI32.dll
    ModLoad: 75c80000 75d49000   C:\Windows\system32\USER32.dll
    ModLoad: 776b0000 776ba000   C:\Windows\system32\LPK.dll
    ModLoad: 774d0000 7756d000   C:\Windows\system32\USP10.dll
    ModLoad: 75fe0000 75fff000   C:\Windows\system32\IMM32.DLL
    ModLoad: 773b0000 7747c000   C:\Windows\system32\MSCTF.dll
    ModLoad: 6d910000 6df80000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    ModLoad: 6d7a0000 6d85e000   C:\Windows\system32\MSVCR100_CLR0400.dll
    (2744.ab8): Unknown exception - code 04242420 (first chance)
    ModLoad: 6c7d0000 6d591000   C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\b58db50e1b6b9a69014a31d72b611c30\mscorlib.ni.dll
    ModLoad: 6c5e0000 6c5f0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll
    ModLoad: 76400000 7655c000   C:\Windows\system32\ole32.dll
    ModLoad: 75640000 7564c000   C:\Windows\system32\CRYPTBASE.dll
    ModLoad: 63b80000 63be0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    (2744.ab8): C++ EH exception - code e06d7363 (first chance)
    (2744.ab8): C++ EH exception - code e06d7363 (first chance)
    (2744.ab8): C++ EH exception - code e06d7363 (first chance)
    (2744.ab8): CLR exception - code e0434352 (first chance)
    
  2. 此时,程序等待用户输入,显示为"按X键退出,否则继续." ;
  3. 虽然依赖的程序集WOMEFLib.dll已经没有了,程序依然能够正常运行到此处,这点比较有趣,为什么加载器没有报”找不到WOMEFLib.dll”的错误呢?答案是Program.Speak()还没有被JIT编译,我们接下来将验证这一点,请先关闭Windbg。

 

Program.Speak方法何时被JIT编译

我们来验证下Program.Speak方法何时被JIT编译,将刚才移动到桌面的WOMEFLib.dll文件再次移动回到Release目录来

  1. 启动Windbg,File-> Open executable,打开Release目录下的WOMEF.exe,按F5继续;
  2. 此时,程序等待用户输入,显示为"按X键退出,否则继续." ;
  3. 在Windbg窗体中,单击菜单 Debug->Break(或者按Ctrl+Break);
  4. 加载CLR,在Windbg命令行中输入”.loadby sos clr”;
  5. 在Windbg命令行中输入”!dumpdomain”命令列出进程中的所有程序集;
    CommandLine: D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    Symbol search path is: *** Invalid ***
    ****************************************************************************
    * Symbol loading may be unreliable without a symbol search path.           *
    * Use .symfix to have the debugger choose a symbol path.                   *
    * After setting your symbol path, use .reload to refresh symbol locations. *
    ****************************************************************************
    Executable search path is: 
    ModLoad: 00b20000 00b28000   WOMEF.exe
    ModLoad: 77570000 776ad000   ntdll.dll
    ModLoad: 71aa0000 71aea000   C:\Windows\SYSTEM32\MSCOREE.DLL
    ModLoad: 760c0000 76194000   C:\Windows\system32\KERNEL32.dll
    ModLoad: 75830000 7587a000   C:\Windows\system32\KERNELBASE.dll
    (1228.1374): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=00000000 ecx=0028f9b0 edx=775b6344 esi=fffffffe edi=00000000
    eip=7760ebbe esp=0028f9cc ebp=0028f9f8 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
    ntdll!LdrVerifyImageMatchesChecksum+0x633:
    7760ebbe cc              int     3
    0:000> g
    ModLoad: 75eb0000 75f50000   C:\Windows\system32\ADVAPI32.dll
    ModLoad: 75e00000 75eac000   C:\Windows\system32\msvcrt.dll
    ModLoad: 76010000 76029000   C:\Windows\SYSTEM32\sechost.dll
    ModLoad: 75d50000 75df1000   C:\Windows\system32\RPCRT4.dll
    ModLoad: 71a30000 71a96000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
    ModLoad: 761a0000 761f7000   C:\Windows\system32\SHLWAPI.dll
    ModLoad: 77750000 7779e000   C:\Windows\system32\GDI32.dll
    ModLoad: 75c80000 75d49000   C:\Windows\system32\USER32.dll
    ModLoad: 776b0000 776ba000   C:\Windows\system32\LPK.dll
    ModLoad: 774d0000 7756d000   C:\Windows\system32\USP10.dll
    ModLoad: 75fe0000 75fff000   C:\Windows\system32\IMM32.DLL
    ModLoad: 773b0000 7747c000   C:\Windows\system32\MSCTF.dll
    ModLoad: 6d910000 6df80000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    ModLoad: 6d7a0000 6d85e000   C:\Windows\system32\MSVCR100_CLR0400.dll
    (1228.1374): Unknown exception - code 04242420 (first chance)
    ModLoad: 6c7d0000 6d591000   C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\b58db50e1b6b9a69014a31d72b611c30\mscorlib.ni.dll
    ModLoad: 6c5e0000 6c5f0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll
    ModLoad: 76400000 7655c000   C:\Windows\system32\ole32.dll
    ModLoad: 75640000 7564c000   C:\Windows\system32\CRYPTBASE.dll
    ModLoad: 63b80000 63be0000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    ModLoad: 73ae0000 73ae8000   WOMEFLib.dll
    ModLoad: 002b0000 002b8000   WOMEFLib.dll
    (1228.22b8): Break instruction exception - code 80000003 (first chance)
    eax=7ffda000 ebx=00000000 ecx=00000000 edx=7760d7eb esi=00000000 edi=00000000
    eip=775a3370 esp=0418fb64 ebp=0418fb90 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll!DbgBreakPoint:
    775a3370 cc              int     3
    0:004> .loadby sos clr
    0:004> !dumpdomain
    *********************************************************************
    * Symbols can not be loaded because symbol path is not initialized. *
    *                                                                   *
    * The Symbol Path can be set by:                                    *
    *   using the _NT_SYMBOL_PATH environment variable.                 *
    *   using the -y <symbol_path> argument when starting the debugger. *
    *   using .sympath and .sympath+                                    *
    *********************************************************************
    PDB symbol for clr.dll not loaded
    --------------------------------------
    System Domain:      6df03478
    LowFrequencyHeap:   6df03784
    HighFrequencyHeap:  6df037d0
    StubHeap:           6df0381c
    Stage:              OPEN
    Name:               None
    --------------------------------------
    Shared Domain:      6df03140
    LowFrequencyHeap:   6df03784
    HighFrequencyHeap:  6df037d0
    StubHeap:           6df0381c
    Stage:              OPEN
    Name:               None
    Assembly:           00336478 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader:        00336518
      Module Name
    6c7d1000            C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    
    --------------------------------------
    Domain 1:           002f1520
    LowFrequencyHeap:   002f189c
    HighFrequencyHeap:  002f18e8
    StubHeap:           002f1934
    Stage:              OPEN
    SecurityDescriptor: 002f2c98
    Name:               WOMEF.exe
    Assembly:           00336478 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader:        00336518
    SecurityDescriptor: 003361a0
      Module Name
    6c7d1000            C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    
    Assembly:           00343588 [D:\Test\Test\WOMEF\bin\Release\WOMEF.exe]
    ClassLoader:        00343628
    SecurityDescriptor: 00342dd8
      Module Name
    00142e9c            D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    
    Assembly:           00352850 [D:\Test\Test\WOMEF\bin\Release\WOMEFLib.dll]
    ClassLoader:        003528f0
    SecurityDescriptor: 00345df8
      Module Name
    001438d0            D:\Test\Test\WOMEF\bin\Release\WOMEFLib.dll
    
  6. 此刻,程序运行至Main方法的第2行,来看看WOMEF.exe的信息,在Windbg命令行中输入”!dumpmodule -mt 00142e9c”,00142e9c是WOMEF.exe的地址,如上的红色字体处;
    0:004> !dumpmodule -mt 00142e9c
    Name:       D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    Attributes: PEFile 
    Assembly:   00343588
    LoaderHeap:              00000000
    TypeDefToMethodTableMap: 001400c4
    TypeRefToMethodTableMap: 001400d0
    MethodDefToDescMap:      00140130
    FieldDefToDescMap:       00140140
    MemberRefToDescMap:      00140144
    FileReferencesMap:       001401a8
    AssemblyReferencesMap:   001401ac
    MetaData start address:  00b220b8 (1780 bytes)
    
    Types defined in this module
    
          MT  TypeDef Name
    ------------------------------------------------------------------------------
    00143810 0x02000002 WOMEF.Program
    
    Types referenced in this module
    
          MT    TypeRef Name
    ------------------------------------------------------------------------------
    6caef568 0x01000001 System.Object
    6caf7574 0x01000013 System.Console
    6cad1fe8 0x01000014 System.ConsoleKeyInfo
    00143dcc 0x01000017 WOMEFLib.ISpeak
    
  7. 再来看看方法表的信息,在Windbg命令行中输入”!dumpmt -md 00143810”,00143810是WOMEF.Program的地址,如上的红色字体处;
    0:004> !dumpmt -md 00143810
    EEClass:      00141424
    Module:       00142e9c
    Name:         WOMEF.Program
    mdToken:      02000002
    File:         D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    BaseSize:        0xc
    ComponentSize:   0x0
    Slots in VTable: 7
    Number of IFaces in IFaceMap: 0
    --------------------------------------
    MethodDesc Table
       Entry MethodDesc      JIT Name
    6c9fa7e0   6c7d4934   PreJIT System.Object.ToString()
    6c9fe2e0   6c7d493c   PreJIT System.Object.Equals(System.Object)
    6c9fe1f0   6c7d495c   PreJIT System.Object.GetHashCode()
    6ca81600   6c7d4970   PreJIT System.Object.Finalize()
    0014c019   00143808     NONE WOMEF.Program..ctor()
    002d0070   001437f0      JIT WOMEF.Program.Main(System.String[])
    0014c015   001437fc     NONE WOMEF.Program.Speak()
    
  8. 可见,方法”WOMEF.Program.Speak()”的JIT状态为NONE,这意味这这个方法还没有被JIT编译,在Windbg中按F5继续运行,在控制台窗体程序中输入任意非’X’字符,CLR编译Program.Speak方法,加载WOMEFLib.dll中的Speak方法;
  9. 再次在Windbg中单击菜单 Debug->Break(或者按Ctrl+Break);
  10. 接着看看方法表信息,在Windbg命令行中输入”!dumpmt -md 00143810”,00143810是WOMEF.Program的地址,如上的红色字体处;
    0:004> !dumpmt -md 00143810
    EEClass:      00141424
    Module:       00142e9c
    Name:         WOMEF.Program
    mdToken:      02000002
    File:         D:\Test\Test\WOMEF\bin\Release\WOMEF.exe
    BaseSize:        0xc
    ComponentSize:   0x0
    Slots in VTable: 7
    Number of IFaces in IFaceMap: 0
    --------------------------------------
    MethodDesc Table
       Entry MethodDesc      JIT Name
    6c9fa7e0   6c7d4934   PreJIT System.Object.ToString()
    6c9fe2e0   6c7d493c   PreJIT System.Object.Equals(System.Object)
    6c9fe1f0   6c7d495c   PreJIT System.Object.GetHashCode()
    6ca81600   6c7d4970   PreJIT System.Object.Finalize()
    0014c019   00143808     NONE WOMEF.Program..ctor()
    002d0070   001437f0      JIT WOMEF.Program.Main(System.String[])
    002d00f0   001437fc      JIT WOMEF.Program.Speak()
  11. 如上,可看到WOMEF.Program.Speak的JIT状态为JIT,需要注意的一点是,若在第8步处按了X键,则WOMEF.Program.Speak不会被JIT编译。因此,当程序走到while循环体内,CLR即时编译并调用方法。
  12. 接下来我们来看看另外一种情景,当控制台程序运行到while循环体之前时,将WOMEFLib.dll复制到Release目录时会是什么状况,先关闭Windbg.

 

第一次等待用户输入时将WOMEFLib.dll复制到程序所在目录会如何

将Release目录中的WOMEFLib.dll剪贴到别的地方,如桌面

  1. 启动Windbg,File-> Open executable,打开Release目录下的WOMEF.exe,按F5继续;
  2. 此时,程序等待用户输入,显示为"按X键退出,否则继续." ,此时将WOMEFLib.dll移动回Release目录中;
  3. 输入任意非’X’字符,此时将会报错,如下:
    技术分享
  4. 这意味着,一旦程序启动,加载器将不会自动重新加载;
  5. 这就是MEF要解决的问题。

以前的解决方案

以上这些只是想让您更加清楚MEF要解决的问题,在开始用MEF之前,先看看如何用现有的技术来解决。在CLR2.0中我们可以在运行时加载程序集,加载后,我们可以创建程序集中定义的某类型的实例,比较简单,如下,在WOMEF项目中移除对WOMEFLib项目的引用,将Program.cs替换为如下代码:

namespace WOMEF
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("按X键退出,否则继续.");
            ConsoleKeyInfo key = Console.ReadKey(true);
            while (key.Key != ConsoleKey.X)
            {
                new Program().Speak();
                key = Console.ReadKey(true);
            }
        }

        public void Speak()
        {
            Console.Write("Speak:");
            InvokeMethod("WOMEFLib", "Speak", "SayHello");
        }

        public object InvokeMethod(string assemblyName, string className, string methodName)
        {
            object returnObject = null;
            try
            {
                Type type = System.Reflection.Assembly.LoadFrom(assemblyName +
                               ".dll").GetType(assemblyName + "." + className);

                MethodInfo mi = type.GetMethod(methodName);
                ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);

                object objectinstance = ci.Invoke(null);
                //Invoke 
                returnObject = mi.Invoke(objectinstance, null);

            }
            catch (TargetException tex)
            {
                throw tex;
            }

            return returnObject;
        }
    }
}


Invoke方法运行时加载WOMEFLib.dll,构造Speak实例,调用SayHello方法。

 

以上内容转载自:http://www.cyqdata.com/cnblogs/article-detail-41697

 

MEF系列一 : MEF简介及解决什么问题

标签:

原文地址:http://www.cnblogs.com/YunGy/p/5044307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!