C#程序集系列05,让程序集包含多个module
本篇体验在一个程序集中包含多个module。
□ 创建3个module
→删除F盘as文件夹中的一些文件,只剩下如下3个文件
→用记事本打开MyFirstModule.cs文件,修改如下,并保存
using System;public class MyFirstModule{public static void Hello(){Console.WriteLine("来自module 1的问候~");}}
→用记事本打开MySecondModule.cs文件,修改如下,并保存
using System;public class MySecondModule{public static void Hello(){Console.WriteLine("来自module 2的问候~");}}
→把MyFirstModule.cs类编译成module
→把MySecondModule.cs类编译成module
→在F盘as文件夹中创建MyThirdModule.cs文件,用记事本打开编写如下代码,并保存
using System;public class MyThirdModule{public static void Hello(){Console.WriteLine("来自module 3的问候~");}}
→把MyThirdModule.cs类编译成module
□ 创建2个程序集并引用运行
现在需要创建2个程序集,一个程序集中包含MyFirstModule和MySecondModule。另一个程序集包含MySecondModule和MyThirdModule。
→创建程序集AssemblyA.dll包含MyFirstModule和MySecondModule。
→创建程序集AssemblyB.dll包含MySecondModule和MyThirdModule。
→编译MainClass.cs文件,引用AssemblyA.dll程序集
以上的dos命令等同于:csc /r:AssemblyA.dll /out:MainClass.exe MainClass.cs
→运行MainClass.exe
→修改MainClass.cs文件
using System;using System;class MainClass{static void Main(){MySecondModule.Hello();MyThirdModule.Hello();}}
→编译MainClass.cs,引用AssemblyB.dll程序集
→运行MainClassAnother.exe
总结:一个程序集是可以包含多个module的。如果将不常用的代码放在单独的module中,就可以减少程序集的载入时间。如果通过网络下载程序集,还可以节约带宽。
关于1楼stg609的问题
问:上面代码中 module1 和 2 是什么时候加载到客户端的?
我们来求证一下:
→删除F盘as文件夹内的所有文件
→在as文件夹下创建MyFirstModule.cs文件,修改如下,并保存
using System;public class MyFirstModule{public static void Hello(){Console.WriteLine("来自module1的问候~");}}
→在as文件夹下创建MySecondModule.cs文件,修改如下,并保存
using System;public class MySecondModule{public static void Hello(){Console.WriteLine("来自module2的问候~");}}
→把MyFirstModule.cs编译成module
→把MySecondModule.cs编译成module
→创建程序集,把MyFirstModule和MySecondModule包含其中
→在as文件夹下创建MainClass.cs文件,修改如下,并保存
using System;class MainClass{static void Main(){MyFirstModule.Hello();}}
其中只用到了一个module。
→编译MainClass.cs文件,引用MyAssembly.dll文件
→运行MainClass.exe
→反编译MainClass.exe可执行文件,并输出到记事本查看IL代码
// Metadata version: v4.0.30319.assembly extern mscorlib{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4...ver 4:0:0:0}.assembly extern MyAssembly{.ver 0:0:0:0}.assembly MainClass{.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ).custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows..hash algorithm 0x00008004.ver 0:0:0:0}.module MainClass.exe// MVID: {7A00D175-6AB5-4EE8-BDDF-EEA3FC87EABD}.imagebase 0x00400000.file alignment 0x00000200.stackreserve 0x00100000.subsystem 0x0003 // WINDOWS_CUI.corflags 0x00000001 // ILONLY// Image base: 0x003B0000// =============== CLASS MEMBERS DECLARATION ===================.class private auto ansi beforefieldinit MainClassextends [mscorlib]System.Object{.method private hidebysig static void Main() cil managed{.entrypoint// 代码大小 8 (0x8).maxstack 8IL_0000: nopIL_0001: call void [MyAssembly]MyFirstModule::Hello()IL_0006: nopIL_0007: ret} // end of method MainClass::Main.method public hidebysig specialname rtspecialnameinstance void .ctor() cil managed{// 代码大小 7 (0x7).maxstack 8IL_0000: ldarg.0IL_0001: call instance void [mscorlib]System.Object::.ctor()IL_0006: ret} // end of method MainClass::.ctor} // end of class MainClass
○ .assembly extern MyAssembly,说明MainClass.exe引用了外部程序集MyAssembly.dll
○ void [MyAssembly]MyFirstModule::Hello(),说明MainClass.exe调用了MyAssembly程序集的Hello方法
可是,依然无法看出2个module是否已经被加载到MyAssembly程序集中!
→反编译MyAssembly.dll
// Metadata version: v4.0.30319.assembly extern mscorlib{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4...ver 4:0:0:0}.assembly MyAssembly{.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows..custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ).hash algorithm 0x00008004.ver 0:0:0:0}.file MyFirstModule.netmodule.hash = (ED 03 41 CA 3F 61 8C 1C FB 06 F2 05 8E 72 9B 86 // ..A.?a.......r..AE 99 CA 28 ) // ...(.file MySecondModule.netmodule.hash = (B0 B3 96 5D C5 9D 56 C6 12 00 6E 03 DF 60 EA 9C // ...]..V...n..`..2F 87 A6 FE ) // /....class extern public MyFirstModule{.file MyFirstModule.netmodule.class 0x02000002}.class extern public MySecondModule{.file MySecondModule.netmodule.class 0x02000002}.module MyAssembly.dll// MVID: {BBC0A811-A24C-4C47-8C24-5A7B96E114C8}.imagebase 0x10000000.file alignment 0x00000200.stackreserve 0x00100000.subsystem 0x0003 // WINDOWS_CUI.corflags 0x00000001 // ILONLY// Image base: 0x003C0000
○ .module MyAssembly.dll,说明MyAssembly.dll中只有一个与程序集名称一致的一个module,FirstModule和SecondModule去哪了?
○ .file MyFirstModule.netmodule,原来FirstModule是作为MyAssembly.dll的外部文件存在的,即当程序集需要MyFirstModule的时候,再去加载。
○ .file MySecondModule.netmodule,SecondModule也是作为MyAssembly.dll的外部文件存在。
至此,就可以回答stg609的问题了:
当客户端调用程序集某个module的方法时,才去加载方法所在的module。因为module1和module2是以外部文件的形式存在于同一个程序集中的,当客户端调用module1的方法,module1才被加载。
“C#程序集系列”包括:
C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序
C#程序集系列02,使用记事本查看可执行程序集的IL代码
C#程序集系列03,引用多个module
C#程序集系列04,在程序集包含多个module的场景下理解关键字internal
C#程序集系列05,让程序集包含多个module
C#程序集系列06,程序集清单,EXE和DLL的区别
C#程序集系列07,篡改程序集
C#程序集系列08,设置程序集版本
C#程序集系列09,程序集签名
C#程序集系列10,强名称程序集
C#程序集系列11,全局程序集缓存
C#程序集系列12,C#编译器和CLR如何找寻程序集
C#程序集系列13,如何让CLR选择不同版本的程序集
参考资料:
http://www.computersciencevideos.org/ created by Jamie King
C#程序集系列05,让程序集包含多个module的更多相关文章
- C#程序集系列04,在程序集包含多个module的场景下理解关键字internal
本篇在一个程序集包含多个module的场景下体验internal的含义. →查看F盘as文件夹下的文件→删除MainClass.exe→把MyFirstModule和MySecondModule组装到 ...
- C#程序集系列10,强名称程序集
当一个程序集的名称,版本,文化,Public Key都做了设置,就可以把这个程序集叫做"强名称程序集".强名称程序集可以防止被仿冒或篡改.本篇首先创建一个强名称程序集,接着模拟篡改 ...
- C#程序集系列08,设置程序集版本
区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...
- C#程序集系列07,篡改程序集
以下几个方面用来区分不同的程序集:○ 程序集名称:Name○ 程序集版本:Version○ 程序集公匙: Public Token○ 程序集文化:Culture 如果没有很严格地按照上面的几个方面来创 ...
- C#程序集系列13,如何让CLR选择不同版本的程序集
本篇主要体验,在存在多个版本程序集的情况下,如何让CLR选择哪个版本程序集运行,以及程序集版本的切换. 分别生成非强名称程序集不同版本 □ 生成某个版本的程序集 →清理F盘as文件夹,剩下如下文件 → ...
- C#程序集系列12,C#编译器和CLR如何找寻程序集
本篇体验C#编译器和CLR运行时如何查找程序集,并自定义CLR运行时查找程序集的方式. □ C#编译器和CLR运行时如何查找程序集 C#编译器在哪里?--在C:\Windows\Microsoft.N ...
- C#程序集系列11,全局程序集缓存
全局程序集缓存(GAC:Global Assembly Cache)用来存放可能被多次使用的强名称程序集.当主程序需要加载程序集的时候,优先选择到全局程序集缓存中去找寻需要的程序集. 为什么需要全局程 ...
- C#程序集系列09,程序集签名
在"C#程序集系列08,设置程序集版本"中体验了为程序集设置版本,但对于程序集的安全性来说,还远远不够.本篇体验程序集的签名. □ 程序集的签名 →F盘as文件夹下有多个文件→在程 ...
- C#程序集系列06,程序集清单,EXE和DLL的区别
CLR在加载程序集的时候会查看程序集清单,程序集清单包含哪些内容呢?可执行文件和程序集有什么区别/ 程序集清单 □ 查看程序集清单 →清空F盘as文件夹中的所有内容→创建MainClass.cs文件→ ...
随机推荐
- 配置vuejs加载模拟数据
[个人笔记,非技术博客] 1.使用前确保安装axios插件,vuejs官方推荐,当然使用其他插件也可以 2.配置dev-server.js var router = express.Router(); ...
- web文件<async-supported>错误分析
<async-supported>true</async-supported> 出现 cvc-complex-type.2.4.a: Invalid content was f ...
- 1089: [SCOI2003]严格n元树
好久没更新了..于是节操掉尽python水过本来就水的题.. n,d=map(int, raw_input().split()) if d==0: print 1 else: f=[1] for i ...
- 推荐 远程部署 fabric
自己写的一个例子: from fabric.api import run, env env.hosts = ['nanjing','hefei','haerbin','lanzhou','taiyua ...
- mysql分布式集群实现原理
做MySQL集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等 有人会问mysql集群,根分表有什么关系吗?虽然它不是实际意义上的分 ...
- Git错误提示之:fatal: Not a git repository (or any of the parent directories): .git
产生原因:一般是没有初始化git本地版本管理仓库,所以无法执行git命令 解决方法:操作之前执行以下命令行: git init 然后执行一下git status查看状态信息,good,问题解决.
- Qt Creator在Windows上的调试器安装与配置
如果安装Qt时使用的是Visual Studio的预编译版,那么很有可能就会缺少调试器(Debugger),而使用MSVC的Qt对应的原生调试器是CDB(对应MinGW的Qt使用GDB调试器).本文介 ...
- Python之路【第十一篇】: 进程与线程理论篇
阅读目录 一 背景知识二 进程2.1 什么是进程2.2 进程与程序的区别2.3 并发与并行2.4 同步与异步2.5 进程的创建2.6 进程的终止2.7 进程的层次结构2.8 进程的状态2.9 进程并发 ...
- ThreadLocal和ThreadLocalMap源码分析
目录 ThreadLocal和ThreadLocalMap源码分析 背景分析 定义 例子 源码分析 ThreadLocalMap源码分析 ThreadLocal源码分析 执行流程总结 源码分析总结 T ...
- 自然语言处理系列-1.什么是NLP?
常常会听到有人说,自然语言处理(NLP)是人工智能技术(AI)皇冠上的明珠.那么,从这句话上就能够看到,目前我们常常说的NLP其实是AI技术的一个分支,而且是较难的那一个分支. 那么,到底什么是NLP ...