程序集种类和部署方式

本章将解释 .Net Framework为了解决版本控制问题而建立的基础结构.

为什么要有强命名程序集?

因为只根据文件名来区分程序集明显不够, CLR必须支持对程序集进行唯一性标识的机制. 这就需要强命名程序集.

私有部署 & 全局部署

  • 私有部署:程序集部署到应用程序基目录或者某个子目录.
  • 全局部署:部署到公认位置的程序集.

强命名程序集 & 弱命名程序集

  • 强命名程序集
    • 使用了发布者的公钥/私钥进行了签名.
    • 这对秘钥允许对程序集进行唯一性的标识.
    • 私有部署和全局部署都可以.
  • 弱命名程序集
    • 只能以私有方式部署.

在生成的程序集中引用强命名程序集

  1. CSC.exe编译器 /r 开关引用,如果不指定目录,按照以下顺序查找
    • 工作目录
    • CSC所在目录
    • 使用/lib 编译器开关指定的目录
    • 使用LIB环境变量指定的任何目录

唯一性标识技术

  • GUID(Globally Unique Identifier) 全局唯一标识符
  • URL(Uniform Resource Locator) 统一资源定位符
  • URN(Uniform Resource Name)

没有使用以上技术,使用了 标准的公钥/私钥加密技术

PublicKeyToken:公钥标记, 如果没null,则是弱命名程序集.

创建强命名程序集

可以使用SN.exe(Strong Name)工具来生成公钥/私钥对。

在VS中,新建公钥/秘钥文件,可显示项目属性,点击签名标签,勾选为程序集签名,然后从选择强名称秘钥文件中新建.

全局程序集缓存

  1. 如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且clr在检测到对该程序集的一个引用时,必须知道自动检查该目录。这个已知的位置成为全局程序集缓存(GAC,Global Assmbly Cache)
  2. GAC通常位于%SystemRoot%\Microsoft\Assembly
  3. GAC目录是结构化的:其中包含许多子目录,并用一个算法来生成这些子目录的名称。不要手动复制.要用工具完成.
  4. 可以使用GACUtil.exe在GAC中安装一个强命名程序集.
  5. 无法将弱命名程序集安装到GAC.

“运行时”如何解析类型引用

  1. 运行应用程序,CLR会加载并初始化自身
  2. 读取程序集的CLR头,查找标识了应用程序入口方法(Main)的MethodDefToken
  3. 检索MethodDef元数据表,找到方法的的IL代码在文件中的偏移量
  4. 将IL代码JIT编译成本机代码.
  5. 最后执行本机代码.

解析引用的类型时候,CLR可以在三个地方找到类型:

  • 同一个文件(早期绑定)
  • 不同的文件但同一个程序集(当前程序集清单目录)
  • 不同的文件不同的程序集(其他程序集清单目录)。  
  • 早期绑定early binding: 编译时便能发现对相同文件中的类型的访问.
  • 晚期绑定late binding: 在运行时通过反射机制绑定到类型并调用方法.
  1. 对于CLR来说,所有程序集都是根据名称、版本、语言文化和公钥来标识的。
  2. GAC根据名称、版本、语言文化和cpu架构来标识程序集。