标签:
首先,什么是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?
---------------------------------------------------------------------------------------------------------------------
通常,创建可重用的代码库并在程序中使用。在传统的Win32应用程序中,如果一个类库被引用至某个应用程序,连接器(Linker)在PE Header中添加此类库的引用。当运行时试图加载应用程序,加载器(Loader)将执行如下操作:
但在.NET环境中,中间有CLR和JIT机制,所以情况有些许不同.加载器只会加载Main方法中使用的那些类库,IL(Intermediate Language,中间语言)将Main方法中调用的其它方法在需要时即时编译(JIT)并加载到内存,这也是MEF的基础之一.
下来看一个明显感觉到需要用到MEF的场景,创建一个控制台应用程序来达到此目的。
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(); } } }
在新的类库项目中定义ISpeak和Speak:
namespace WOMEFLib { public interface ISpeak { void SayHello(); } }
namespace WOMEFLib { public class Speak:ISpeak { public void SayHello() { Console.WriteLine("Hello World!"); } } }
在WOMEF项目中添加对WOMEFLib项目的引用,解决方案中右键WOMEF项目,属性\生成\配置,选择”Release”,保存、生成、调试,这都不是我们关注的重点,我们要关注的是这两个程序集的相关的问题。
我们将要验证以下几点:
要验证以上几点,我们需要在运行时查看方法列表及程序集信息,以下将围绕这几点进行阐述。
需要用到的工具,Windbg,MSIL 反汇编程序,关于这两个工具可从 这里下载安装 。
有关SOS 调试扩展的资料可参考这里。
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
(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
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: 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
ConsoleKeyInfo key = Console.ReadKey(true);虽然还没有使用WOMEFLib.dll中的任何东西,但依然被加载,这是为什么呢?因为WOMEFLib.dll已经在WOMEF.exe的manifest中,请先关闭Windbg。
接下来我们测试下当缺少WOMEFLib.dll时会发生什么,将Release目录中的WOMEFLib.dll剪贴到别的地方,如桌面,
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)
我们来验证下Program.Speak方法何时被JIT编译,将刚才移动到桌面的WOMEFLib.dll文件再次移动回到Release目录来
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
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
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()
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()
将Release目录中的WOMEFLib.dll剪贴到别的地方,如桌面
以上这些只是想让您更加清楚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
标签:
原文地址:http://www.cnblogs.com/YunGy/p/5044307.html