Assembly Essence 程序集深入探讨:程序集结构及部署

1. Assembly definition
    Assembly简单来说,就是一个以CLR为宿主、版本化的、自描述的二进制文件。需要注意的是,.Net framework里面的Assembly虽然文件名也是dll或者exe,但是其和传统意义上的dll却是不一样的。最为关键的是,Assembly是一种自描述的文件,在其内部包含了大量描述其自身内容的信息。

2.Assembly程序集结构(格式)
    一般来说,程序集包括以下几个部分:
    1、头文件信息:Win32头文件+CLR头文件(Win32 header file + CLR header file)
    2、CIL代码(CIL code)
    3、类型元数据(type MetaData)
    4、程序集清单(Assembly Manifest)
    5、可选的嵌入资源(optional embemed resources)

    下面具体介绍每个部分的作用:
    1、Win32 header file和CLR header file
        Win32头文件块包含了Assembly被windows系统加载的时候所提供的必要信息。这些头部信息标示了Assembly将以什么类型(是基于console,基于GUI还是*.dll)驻留在windows OS中。
           我们可以使用.net SDK 工具 dumpbin.exe /headers 来查看其header file。
        CLR header file信息定义了多个标记,他们使得CLR可以了解到Assembly的布局。例如,这些标记标示了MetaData和资源的位置、Assembly构建的运行库版本,publickey(optional)等。
        我们可以使用.net SDK 工具 dumpbin.exe /clrheader 来查看其header file。

    2、CIL代码
    Assembly的核心部分包含CIL代码,这些CIL代码是独立于平台和CPU的中间语言(platform-independent&CPU-independent)。在运行时,Assembly里面的CIL被JIT compiler(Just-In-Time)编译成特定平台和CPU的指令。在这种机制下,.NET Assembly可以在多种不同的架构、设备和操作系统下运行。

    3、类型元数据(Type MetaData)
    Assembly MetaData完整地描述了Assembly内含类型和reference type。

    4、程序集清单(Assembly Manifest)
     程序集清单是Assembly内非常重要的部分,该清单详细记录了程序集中的每一个模块、构建程序集的版本以及该程序集引用的所有外部程序集,以及所引用程序集的pubic key token(如果有的话)。
        扩展话题:
        问:Assembly如何利用Strong Name来识别所引用的Assembly的?
        答:我们知道,在一个Assembly(设为MainAssembly)里面引用一个具有Strong name的Assembly(设为referencedAssembly,假设其public key token为PKT1)的时候,该MainAssembly的Manifest里面会记录该被引用的referencedAssembly的public key token,即为PKT1。 当MainAssembly在运行的时候,当CLR加载referencedAssembly的时候,CLR会将MainAssembly Manifest里面所记录的引用referencedAssembly的public key token 与 referencedAssembly的public key token进行比较。 如果能够match,则将其Load;否则抛出FileNotFound Exception.


A
ssembly Deployment methods程序集部署方式

     An assembly can be deployed via two methods alternatively
    a) private method私有程序集
    deploying the assembly with the app in the same directory is called private deployment. Weak Name Assembly can only be deployed via priviate deployment..
    所有没有发布的Assembly称为private Assembly。当client引用private Assembly的时候,会在client所在路径下创建一个该Assemly的副本。
    因此,在发布这类Application的时候,只需要与referenced Assembly一起copy放到机器的某个位置即可,这种部署方式也就是所谓的Xcopy部署

    b) Global method(共享程序集或者公共程序集)
    Global deployment can deploy the assembly place where CLR can identify. as CLR search in the assemblies, it knows to find in such specific path. Strong Name Assembly can be deployed via Global Deployment as welll as private deployment.
    一个程序集可以通过2种方式发布:私有方式和全局方式

How to deploy Strong Name Assemly via Global Deployment如何通过全局部署发布强签名程序集   
    a)deploy to Where?
    if an assembly will be access by more than one applications, then it should be deployed via Global deployment. it should be deployed under a recognized directory by CLR, as long as app requires access specific assembly, the CLR can find it.this recognized direcoty is call GAC (Global Access Cache:全局程序集访问缓存) which is located on the windows system path normally . such as C:\Windows\Assembly\GAC or C:\winnt\Assembly\GAC
    如果一个程序集被多个程序访问,那么该程序集必须全局发布,共享程序集必须采用强签名(strong name)。该程序集必须发布在某个CLR所认识的目录下。当程序需要访问程序集的时候,CLR必须能够找到它。这个CLR所认知的目录一般命名为GAC, 他一般位于系统目录下,比如c:\windows\Assembly\GAC。
    b) GAC interior constructure GAC内部结构
    using comamd Line, we can see that there are many directories, and related assebly file is stored in which. such as in Dir System.XML ,there is a file called 1.0.5000.0_b73afaffa93dafa89
, this file is combined with the following parts:
        (Version)_(Culture)_(PublicKeyToken)
 so 1.0.5000.0_b73afaffa93dafa89 means 
                version=1.0.0.5 
                culture=neutral, 
                publicKeyToken=b73afaffa93dafa89
if the culture is China, then it will be 1.0.5000_cn_b73afaffa93dafa89 
    在命令行模式下,我们可以看到GAC下面有很多目录,每个目录下面存放其相应的程序集文件,程序集文件的命令由几部分组成:    
    (版本)_(文化)_(公钥令牌)

     c) How to Deploy如何部署
        the most frequently used tool is GACUtil.exe to deploy strong name assembly.
        How to sign an Assembly using Strong name, please refer to my another report:
 http://www.cnblogs.com/Winston/archive/2008/04/23/1026489.html
        1) gacutil /i myAssembly.dll  deploy myAssembly.dll that has be signed with strong name.
        2) gacutil /u myAssembly.dll  uninstall myAssembly .
        最常用的工具是gacutil ,其用来部署程序集
        gacutil /i 用来部署强程序集
        gacuitl /u 用来卸载强程序集
原文地址:https://www.cnblogs.com/Winston/p/1167845.html