.Net Framework 之 托管模块与程序集的关系

一、基本概念:
--托管模块:一个标准的32的可移植执行体(PE32)文件或一个标准的64位可移植执行体(PE32+)文件。由用支持CLR的任何一种语言创建的源代码文件,再经过相应的编译器检查语法和分析源代码,编译生成。如下:
 
--程序集:由一或者多个模块/资源文件的逻辑性组合。程序集是重用、安全性以及版本控制的最小单元。
    可以将.exe与.dll文件认为是一个程序集;其中.exe文件是一个自己执行的程序集,而.dll将被其他程序集加载后运行。
 
二、模块与程序集概念的类比
    一个项目的开发团队,会有一个或者是多个的“成员”组成,这些“成员”里必定会有一个负责人。团队外部的人要和这个团队打交道,他们只需要知道这个团队的负责人即可。因为这个负责人“成员”知道这个团队内部的一切情况。在很多情况下,团队外部的人员会以负责人的名称来称呼这一个团队。在这里,团队是一个逻辑的概念,并不是特指某个人或资源。
    团队 = 程序集
    负责人 = 主模块(下面会说明与普通模块的区别)
    成员 = 普通模块
    在很多情况下,我们会用主模块的特征(如名称)来称呼一个程序集。即(用负责人“成员”的特征来称呼一个团队)
    
三、模块与程序集的生成
1、cs文件
假设我有两个.cs的类库文件,和一个包含Main方法的.cs文件,都放在D: est文件夹中。分别为:
Cat.cs:
namespace Animal
    {
        {
 
    }
Dog.cs:
namespace Animal
    {
        {
 
    }
Program.cs
public class Program
    {
        new Cat().Print();
 
2、生成类库程序集
现在可以将这两个.cs文件生成相应的模块,利用csc.exe编译器:
csc /t:module /out:D: estCat.netmodule D: estCat.cs
csc /t:module /out:D: estDog.netmodule D: estDog.cs
 
这个会在D: est目录下生成两个普通模块:
Cat.netmodule
Dog.netmodule
 
由于CLR是以程序集作为最小单元进行加载的,为了使Program.cs文件能够正常地调用Cat.netmodule与Dog.netmodule/现将这两个文件生成一个程序集。由于这个程序集是一个被其他程序集加载的,因此,生成的文件名可以为:Animal.dll
csc /out:D: estAnimal.dll  /t:library /addmodule:D: estCat.netmodule;D: estDog.netmodule
执行此命令之后,会在D: est目录下生成Animal.dll
 
上面的各个模块中:
主模块(负责人):Animal.dll
普通模块(成员): Cat.netmodule, Dog.netmodule。
程序集(团队):由主模块Animal.dll与普通模块Cat.netmodule、Dog.netmodule组成。但是在一般情况下我们会将Animal.dll称为程序集。特别是在IDE 的visual studio的生成的情况下,因为在IDE默认生成的dll中,已经将各个模块包含进dll中,除了dll中,并没有其他的模块文件。
在这里,我们可以运行命令:
csc /out:D: estAnimal.dll /t:library D: estCat.cs D: estDog.cs直接生成Animal.dll文件,此时将不再生成Cat.netmodule与Dog.netmodule文件;
 
3、exe调用dll
执行命名:
csc /out:D: estProgram.exe /R:D: estAnimal.dll D: estProgram.cs    
将会在D: est生成Program.exe可运行文件
注意:这里的Animal.dll文件代表的是一个程序集,如果这个程序集由多个文件组成,必须保证其他文件都存在,否则编译会失败。如当程序集由主模块Animal.dll、普通模块Cat.netmodule与Dog.netmoudle组成时,必须保证这三个文件同时存在。
 
 
在命令行中可以直接执行: Program.exe
输入结果:
    dog
    cat
 
4、一个程序集多个模块的作用
    CLR是以程序集为单位进行加载的。但是,CLR只会加载被引用到的模块,没有引用的模块不会加载。因此,可以将程序集分为多个模块,运行程序时,只要保证有被引用到的模块存在即可,可以减少加载的程序集文件大小;特别是当程序集是通过网络传输加载时。
示例:
    修改Program.cs文件,使它不再引用Cat.cs文件中的类型
public class Program
    {
         // new Cat().Print();
}
 
重新编译Program.cs文件:
csc /out:D: estProgram.exe /R:D: estAnimal.dll D: estProgram.cs   
现在在D: est文件夹中具有文件如下:
运行Program.exe,结果:
现在将Cat.netmodule删除:
运行Program.exe,结果:
原因是:CLR并没有加载Cat.netmodule,因此,就算这个普通模块不存在也无所谓。
原文地址:https://www.cnblogs.com/xinaixia/p/5767847.html