使用程序集和模块

 

程序集预览(Assembly Overview        <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

        任何.NET二进制代码使用的.NET运行时是一个或一组程序集组成的。当你编译一个应用程序时,实际上是在创建一个程序集。

        任何时候构建一个EXEDLL文件时必须使用/t:library编译参数创建与该应用程序相对应的包含清单(manifest)的程序集,清单(manifest)记录了.NET运行时程序集的相关信息。另外,使用/t:module编译参数,创建一个以.netmodule为扩展名的DLL 文件,这个DLL文件不包含清单。换句话说,虽然逻辑上模块(module)依然是一个DLL文件,但是它不属于程序集,当编译应用程序或使用程序集生成工具(the Assembly Generation tool)时必须使用/addmodule开关将这个DLL文件加入到其他程序集中。

清单数据(Manifest Data

       程序集的清单有不同的方法存储。若编译一个独立的应用程序或DLL文件,清单与程序或DLLPE结合在一起,这称为单一文件的程序集(single-file assembly)。多文件程序集(multifile assembly)是指清单以另外一个独立实体的形式作为程序集的一部分,或者作为程序集中的一个模块。

       同样程序集的定义很大程度取决你如何使用它。从客户的角度来看,程序集是模块、导出类型、(必需、可选)资源的命名和版本化(versioned)的集合。从程序集创建者的角度来看,程序集是客户能使用的一组相关联的模块、类型、资源、导出的方法的封装包(mean of packaging)。也就是说,清单是程序集和用户之间沟通的桥梁。下面列出程序集中清单包含的信息:

·          程序集名称(Assembly name

·          版本信息(Versioning information

        版本信息是由四个不同的部分组成的版本号,分别是主版号、子版号、构建序号、修订号。

·          (可选的)共享名和带符号的程序集散列(AnOptionalshared name and signed assembly hash

        主要是关于程序集部署的相关信息。

·          文件(Files

         包含在程序集中的文件列表。

·          引用的程序集(Referenced assemblies

         直接引用的外部程序集列表。

·          类型(Types

        程序集内部的所有类型及模块映像包含的类型的列表。(This is list of all types in the assembly with a mappig to containing the type.

·          安全(Security

        安全权限的列表,权限已明确地被程序集抛弃。(permissions This is a list of security permissions that are explicity refused by the assembly.

·          定制属性(Custom attributes

·          产品信息

        包含公司、商标、产品及版权信息。

 

程序集的优势

·          程序集的封装:将多个模块封装到一个物理文件,起到性能优化的作用。当你创建一个应用程序并使用多文件程序集时,.NET运行时只需加载相关的模块。这种策略起到减少应用程序的工作集。

·          程序集的部署

             .NET框架中程序集是最小的部署单元。虽然它诱人的说,程序集是部署应用程序的方法,但是技术上并不是如此。许多关于程序集部署的正确的观点是:在.NET中程序集应该看作一个窗体的类部署(class deployment)-就像Win32中的一个DLL文件。一个单独的应用程序是由多个程序组成的。

             因为程序集是自描述的(self-desciribing),所以部署程序集最简单的方法就是直接把程序集复制到目的文件夹。当尝试运行包含这个程序集的应用程序时,清单将向.NET运行时提供包含在这个程序集中的方法信息。另外,清单(manifest)也向应用程序提供该程序集所引用的外部程序集的相关信息。

             许多通过公共方法部署的程序集依然是私有的程序集,即程序集被复制到文件夹,但它们不是共享的。缺省情况下程序集是私有的,除非明确地指定程序集为共享程序集(shared assembly)。

·          程序集的版本

             使用程序集另外一个主要优势是程序集内置了版本号。程序集中止了DLL地狱。DLL地狱是指当一个应用程序重写了一个被其他应用程序引用的DLL文件,而该应用程序引用的是低版本的同名DLL文件,这就造成了引用低版本DLL的应用程序运行出错,这种情况。虽然Win32资源文件格式内置了版本资源类型,但是操作系统不会强制执行任何版本控制,以便依赖这个DLL文件的应用程序能正常运行。

             基于这个问题,清单不仅包含程序集本身的版本信息,也包含了该程序集所有被引用的程序集和这些程序集的版本信息。因为有了这个体系结构,.NET运行时能确保版本规则被支持,当出现新版本的程序集时,版本不兼容的共享DLLs由操作系统自动安装,使得应用程序可以继续正常运行。

None.gif //  DllTestServer.cs
None.gif
//  Build with the following command-line switches:
None.gif
//      csc /t:library DllTestServer.cs
None.gif
public   class  DllTestServer
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static void Foo()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        System.Console.WriteLine(
"DllTestServer.Foo " +
InBlock.gif            
"(DllTestServer.DLL)");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
//  DllTestClient.cs
None.gif
//  Build with the following command-line switches:
None.gif
//      csc DllTestClient.cs /r:DllTestServer.dll 
None.gif
using  System;
None.gif
using  System.Diagnostics;
None.gif
using  System.Reflection;
None.gif
None.gif
class  DllTestClientApp
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Assembly DLLAssembly 
=
InBlock.gif            Assembly.GetAssembly(
typeof(DllTestServer));
InBlock.gif        Console.WriteLine(
"\nDllTestServer.dll Assembly " +
InBlock.gif            
"Information"); 
InBlock.gif        Console.WriteLine(
"\t" + DLLAssembly);
InBlock.gif
InBlock.gif        Process p 
= Process.GetCurrentProcess();
InBlock.gif        
string AssemblyName = p.ProcessName + ".exe";
InBlock.gif        Assembly ThisAssembly 
= Assembly.LoadFrom(AssemblyName);
InBlock.gif        Console.WriteLine(
"DllTestClient.exe Assembly " +
InBlock.gif            
"Information"); 
InBlock.gif        Console.WriteLine(
"\t" + ThisAssembly + "\n");
InBlock.gif
InBlock.gif    Console.WriteLine(
"Calling DllTestServer.Foodot.gif");
InBlock.gif    DllTestServer.Foo();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
 

用多个模块创建程序集(Creating Assembies with Multiple Modules

   模块是基于DLL,但是它不是真正意义上的DLL,它必须被包含程序集中。示例:
None.gif //  NetModuleTestServer.cs
None.gif
//  Build with the following command-line switches:
None.gif
//      csc /t:library NetModuleTestServer.cs
None.gif
public   class  NetModuleTestServer
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static void Bar()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        System.Console.WriteLine(
"NetModuleTestServer.Bar(NetModuleTestServer.netmodule)");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
//  NetModuleTestClientApp.cs
None.gif
//  Build with the following command-line switches:
None.gif
//
None.gif
//  csc addmodule:NetModuleServer.netmodule NetModuleTestClientApp.cs
None.gif
using  System;
None.gif
using  System.Diagnostics;
None.gif
using  System.Reflection;
None.gif
None.gif
class  NetModuleTestClientApp
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Assembly DLLAssembly 
= Assembly.GetAssembly(
InBlock.gif            
typeof(NetModuleTestServer));
InBlock.gif        Console.WriteLine(
"\nNetModuleTestServer.dll Assembly " +
InBlock.gif            
"Information");
InBlock.gif        Console.WriteLine(
"\t" + DLLAssembly);
InBlock.gif
InBlock.gif        Process p 
= Process.GetCurrentProcess();
InBlock.gif        
string AssemblyName = p.ProcessName + ".exe";
InBlock.gif        Assembly ThisAssembly 
= Assembly.LoadFrom(AssemblyName);
InBlock.gif        Console.WriteLine(
"NetModuleTestClient.exe Assembly " +
InBlock.gif            
"Information");
InBlock.gif        Console.WriteLine(
"\t" + ThisAssembly + "\n");
InBlock.gif
InBlock.gif        Console.WriteLine(
"Calling NetModuleTestServer.Bardot.gif");
InBlock.gif        NetModuleTestServer.Bar();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

 

创建共享程序集

   若要创建一个在多个应用程序使用的程序集,并且版本信息相当重要,则必须共享程序集。若要共享程序集,必须给程序集指定强名称。可以通过.NET SDK提供强名称工具(the Strong Name tool)创建强名称。使用强名称有四个主要理由:

·          它是.NET生成唯一的全局名称的机制

·          因为强名称工具生成的密钥对包含了一个签名,你可以判断程序集创建之后是否被篡改。(Because the generated key pair includes a singature,you can tell whether an assembly has been tampered with after its original creation.

·          强名称能防止第三方在你构建的程序集的基础上发表新的版本。这是因为密钥对包含签名起了作用,因为第三方不知道你的私钥。

·          当.NET加载程序集时,运行时会自动验证调用者是否合法。(When .NET load an assembly,the runtime can verify that the assembly came from the publisher that the caller is expecting.

创建强名称的步骤:

·          使用强名称工具为程序集创建一个强名称。示例:

    sn -k InsideCSharp.key

·          在客户端源代码文件中添加属性AssemblyKeyFile,把强名称指定给程序集。

 

使用全局程序集缓存工作

   .NET每次加载程序集时都会创建一个代码缓存区,通常成为全局程序集缓存。使用全局程序集缓存有三个作用:

·          存储从Internet或文件服务器下载的代码。注:从一个特定的应用程序加载的代码存储在缓冲中的私有区域,以防止其他程序集访问。

·          存储被多个.NET应用程序共享的组件数据。利用全局缓存工具将程序集加载到缓存全局区域,使得该程序集可以被本地机器的所有应用程序访问。

·          程序集的本地代码是预运行时编译的,同时存储在全局程序集缓存区。(native code versions of assemblies that have been preJITted are stored in the cache.

 

缓存视图

1、在windows\assembly文件夹中可以查看程序集的相关信息,如版本号、语言(culture)、公钥标记等等信息。

2 、在命令行使用 gacutil 。其中 -i 参数:加载程序集; -u 参数:卸载程序集(可以指定版本号)、 -l 参数:列出程序集的相关信息。

转载于:https://www.cnblogs.com/stzyw/archive/2005/08/25/222361.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值