托管程序的部署是以程序集(Assembly)为基本单元的。前面说过,一个程序集包含若干个托管模块(exe或dll)。但通常,一个程序集只包含一个dll或exe(在vs中也仅支持这种)。为了生成含多个托管模块的程序集可以用编译器csc.exe或vbc.exe,或者是使用链接器al.exe。这种方式通常会用于分离常用库和非常用库(后面会提到)。程序集是一个逻辑概念,它在某一个托管模块中放置描述程序集信息的清单(manifest)。
程序集可以分成两种,一种是强命名的,一种是非强命名的(Jeffrey Richter称为弱命名)。强命名的程序集包含四个唯一标识程序集的特征:文件名,版本号,语言文化标识和公有密钥标记。简单的说,这些信息足够一个开发人员标识一个程序集,而不会与其他的程序集产生命名冲突。相比之下,非强命名则不要求这些信息。
了解程序集的相关内容。再来看一下部署方式。程序集的部署方式分成两种,一种是私有部署,另一种是全局部署。非强命名程序集只能以私有方式部署,而强命名的可以用两种方式部署。私有部署的程序集一般只能被一个应用程序使用,而全局部署的程序集可以被所有的程序使用,安装.Net Framework的类库就是全局部署的(但它会在本地产生副本),它可以节约磁盘资源。私有部署一般都是简单的拷贝到机器上即可(假设有环境),也可以像普通程序一样安装(程序调用了COM的时候是必须的)。在.Net环境中,这是一个很好的部署方式,方便且安全,除了考虑需要共享的场合,都应该采用这种方式。而全局部署很适合框架程序的部署(总之就是有共享需求的场合),为了避免Dll Hell,程序集的部署采用了一种不同与以往的策略。在机器上一般都有一个目录称为GAC(Global Assembly Cache),常位于C:\Windows\Assembly\GAC(或者其他CLR明确知道的地方)。查看这个文件夹是一件和有意思的事情,在资源管理器中只能到达C:\Windows\Assembly。要想了解其中的奥妙,只能用控制台操作。强程序集会建立一个与其特征标识相配套的目录结构(可视为:名字\版本\文化\密钥),这样的机制保证不同公司,不同版本的程序集都不会产生冲突,避免了Dll Hell。个人觉得这是一种以空间换安全的方式。因为通常老版本的程序集是不会被删除(因为不知道都有谁在用了),其结果会造成GAC越来越大。因此,做为开发人员,应该仔细考虑是否真的需要向GAC中部署程序集。
在程序集的部署,发布以及后面要说得调用中。配置文件都是很重要的一部分。部署策略,搜索策略等等都是通过配置文件来设置的。配置文件通常跟随exe文件。一般的应用程序与exe同目录,名字为exe文件全名(含扩展).config;Asp.net为web.config。全局的配置文件为machine.config。它做一些基础的配置工作。
恩。最后说程序是如何加载一个程序集的。加载程序集发生在运行IL需要一个新的程序集的情况。从普遍的情况来看,当IL执行到某一个方法时,该方法是第一次执行。这时候就需要编译该方法(JIT方式)。如果这个方法是处于一个没被加载的程序集中,CLR就会加载该程序集。加载程序集分成如下几步:
1.判断一个程序集是否是强程序集,如果是,则在GAC中搜索该程序集。
2.如果程序集是非强程序集或在GAC中搜索失败,则到配置文件中的codeBase中搜索该程序集。codeBase是配置文件中的一项,是一个URL。允许加载本地和远程的程序集。上面说一个程序集中包含多个托管模块也是这个用途,利用URL使得不同模块可以不同时间下载到本地。
3.如果仍查找失败,会进入私有目录的检索。通过配置文件的设置,可以配置出与文化,子目录等相关的搜索方式。
4.如果在此处也未能找到,查找宣告失败,抛出异常。
这是我对整个过程的理解,强烈建议去看一看.Net 框架程序设计的第二第三章。有详细的描述。不愧为圣经的美誉。