微软Windows应用程序经常受到动态链接库的拖累,这就是“DLL地狱”问题,在遇到此类麻烦的时候,应用程序的某一个组件会被其他应用程序的不兼容组件覆盖,结果令受到干扰的应用程序完全不能正确工作。这些问题很难诊断出来,因为它们只有在问题组件安装一段时间之后才会突然冒出来。Visual Basic应用程序的DLL地狱问题更是臭名昭著,因为用Visual Basic语言开发的应用程序相比其他编程语言开发的应用程序具有更大程度的外部相关性。微软推出的.NET计划有望采用一种新型的分布单元assembly(装配)来缓和这一严重问题。
从编程的角度来看,一个assembly在功能上等同于Java包:它提供了相关类的可分配库而且定义了它们的范围。对那些不熟悉Java的人来说,在开发应用程序的时候,assembly之于.NET无异于DLL文件之于COM,只不过assembly由多个文件所组成。
Assembly可以通过所谓的名单(manifest)实现自我文档化,这也是它们相比DLL更为优异的一个典型特征。名单包含在assembly之内,由说明assembly的导出类的元数据、这些类所需的外部依附、使用assembly所需的权限以及此类依附的版本控制信息所组成。在.NET框架内,assembly为版本、类以及不能版本化的单个文件提供了公共名称。这样就可以不必检查多个文件以确定系统上安装组件的版本,这也正是我们以往最感到气恼的地方。.NET的这种版本控制特性几乎可以完全消除DLL地狱病。
在缺省的情况下,.NET的assembly是私有的,这意味着它们仅能被某一个应用程序所用。私有的assembly应当被安装到应用程序所在的文件夹或其子文件夹之一。微软希望大多数 .NET开发人员能采用私有的assembly,而事实上它也在鼓励人们这样做。
但是,这样会带来一个潜在的问题:用户的硬盘内可能因为拥有同一私有assembly的多重拷贝而变得混乱不堪,这真是很具有讽刺意味,听起来反倒是COM好象更容易解决这个问题了。微软则是这样回应以上批评的:“硬盘很便宜,买个更大的就行了。”幸好,你可以非常方便地把私有的assembly转为公共assembly,甚至不必重新编译或编辑代码。
共享assembly和私有assembly之间的主要差别在于前者通常保存在专门命名的全局装配缓存(简称GAC)内。GAC有时在微软文档中被称为Global Assembly Store,可能是因为后者简称起来好听一些。
GAC能存储同一assembly的多个版本,这就是微软所称的“肩并肩部署”功能。这一功能几乎消除了安装应用程序的不兼容共享组件而影响其他应用程序的可能性,这对开发者来说肯定是个好消息。
客户assembly能指定它兼容哪个或者那些共享assembly的版本。如果客户程序的版本要求不能被满足,那么.NET运行时就不会装载任何服务器assembly。顺便说一句,.NET的assembly版本由4位数字格式表示,形式如:主版本号.次版本号.创建版本号.修订版本号。
默认地。一个assembly被认为只能兼容具有同样主版本和次版本号的共享assembly。然而运行时装载器却优先装载相比客户版本具有更高创建版本号或者修订版本号的assembly,如果存在这样的assembly,就会自动地为其提供修补支持。这种缺省行为并不一定总是你所希望的,因此程序员或系统管理员可以定义定制的版本控制策略,比方说,强迫装载某一特定的版本或者禁用装载器对更高创建版本号或者修订版本号的assembly的装载。
在Beta 1版上,版本控制策略包含在一些XML文件内,而这些文件则要不驻留在应用程序目录下要不就保存在Windows目录下。这些XML文件分别定义了同特定软件相关的版本策略以及系统范围内的版本控制策略。
你可以随意命名私有的assembly,只要其名称在应用程序内唯一即可。另一方面,公共assembly则需要采用某种全局唯一标识符以便.NET运行时可以识别它们。COM的Class ID和Prog ID已经随风而逝了。现在的共享assembly采用了所谓的strong name命名机制。Strong name来源于标准的公钥加密算法。开发人员用一个私钥“签署”assembly同时提供一个公钥供客户assembly使用。公钥随后成为assembly的strong name的一部分。
采用命令行编译器签署assembly需要使用一些命令行指令选项,因此这也是一项比较繁重的任务。幸好,Visual Studio.NET可以自动地为程序员完成这些工作。
微软最后还是承认了DLL地狱问题的存在,而且意识到这一问题只能通过操作系统级施加控制策略才能得以弥补。在注册表和对COM应用程序单个组件支持这方面瞎折腾一气之后,看起来好象微软已经走上了正途。事实上,有了assembly机制,安装.NET应用程序完全可能变成使用Xcopy命令拷贝程序那么简单!