多文件程序集

Nit*_*ess 5 .net assemblies .net-assembly

拥有一个物理编码在多个.cs文件中的单个文件程序集和一个具有多个.NetModules的多文件程序集之间有什么区别和优势?

我的教授说,当这些组件加载或在jitting期间可以实现差异.并非所有多文件程序集的.Netmodules都会立即加载.但即使他不确定.有人能澄清我吗?

Moh*_*ari 9

让我们假设我们调用了两个.cs文件
RUT.cs,其中包含很少使用的类型
FUT.cs,其中包含常用类型.
现在,csc /t:module RUT.cs
这行使C#编译器创建一个RUT.netmodule文件.此文件是标准DLL PE文件,但是,CLR本身无法加载它.

接下来让我们将常用类型编译到自己的模块中.我们将使这个模块成为程序集清单的守护者,因为这些类型经常被使用.事实上,因为这个模块现在将代表整个程序集,我将输出文件的名称更改为JeffTypes.dll而不是将其命名为FUT.dll:

csc /out:JeffTypes.dll /t:library /addmodule:RUT.netmodule FUT.cs
Run Code Online (Sandbox Code Playgroud)

该行告诉C#编译器编译FUT.cs文件以生成JeffTypes.dll文件.因为指定了/ t:library,所以将包含清单元数据表的DLL PE文件发送到JeffTypes.dll文件中./addmodule:RUT.netmodule开关告诉编译器RUT.netmodule是一个应该被视为程序集一部分的文件.具体来说,/ addmodule开关告诉编译器将文件添加到FileDef清单元数据表中,并将RUT.netmodule的公开导出类型添加到ExportedTypesDef清单元数据表中. 在此输入图像描述

RUT.netmodule文件包含通过编译RUT.cs生成的IL代码.此文件还包含元数据表,用于描述由RUT.cs定义的类型,方法,字段,属性,事件等.元数据表还描述了RUT.c引用的类型,方法等.JeffTypes.dll是一个单独的文件.与RUT.netmodule一样,此文件包含通过编译FUT.cs生成的IL代码,还包括类似的定义和引用元数据表.但是,JeffTypes.dll包含其他清单元数据表,使JeffTypes.dll成为程序集.其他清单元数据表描述组成程序集的所有文件(JeffTypes.dll文件本身和RUT.netmodule文件).清单元数据表还包括从JeffTypes.dll和RUT.netmodule导出的所有公共类型

现在,如果某些clinet代码重新生成到JeffTypes.dll正在执行,则在第一次调用方法时,CLR会检测该方法引用的类型作为参数,返回值或作为局部变量.然后CLR尝试加载包含清单的引用程序集的文件.如果正在访问的类型在此文件中,则CLR执行其内部簿记,允许使用该类型.如果清单指示引用的类型位于不同的文件中,则CLR会尝试加载必要的文件,执行其内部簿记,并允许访问该类型.仅当调用引用卸载程序集中的类型的方法时,CLR才会加载程序集文件.

这意味着要运行应用程序,不需要存在引用程序集中的所有文件.
因此,较少使用的源类可以在NetModules中编译并在必要时加载,提高性能减少Dll文件大小可以简化变更管理和部署过程.

图片和 杰弗里·里奇特的一些报价