基本定义
强命名 (strong name) 由一个程序集的标识组成并通过公钥和数字签名(针对该程序集生成)加强的名称,其中的标识包括程序集的简单文本名称、版本号和区域性信息(如果提供的话)。
概念提出的根源
(Name、Version和Culture)完全相同的情况是有可能发生的,如此一来,这唯一标识程序集可重任就落到PublicToken的头上了。强命名的程序集正是使用RSA来保证PublicToken的唯一性,因为在理论上,非对称算法RSA生成的公钥/私钥对不会重复。.Net正是通过在编译项目时将指定的公钥/私钥对写入程序集来保证其唯一性。
对于全局程序集缓存(GAC),MSDN是这样介绍的:安装有公共语言运行库的每台计算机都具有称为全局程序集缓存的计算机范围内的代码缓存。全局程序集缓存中存储了专门指定给由计算机中若干应用程序共享的程序集。
在开发一般的、非共享的程序时,我们不需要使用强命名的程序集,仅将项目(Project)编辑成.DLL或者.EXE即可。但是,如果我们开发的是组件库、框架时,通过对程序集进行强命名,并使用将其部署到GAC中,可以保证我们的程序集不会出现版本问题。
全局程序集缓存(GAC)
1. GAC的概念
如果一个Assembly要被多个应用程序访问,那么他就必须放在一个CLR已确知的目录下,并且CLR在探测到有对该Assembly的引用时,它必须能自动到该目录下寻找这个程序集。这个已确知的目录称作GAC(Global Assembly Cache),就是全局程序集缓存。它一般位于下面的目录下:<System Drive>:/Windows/Assembly/GAC。
GAC的作用就是提供给CLR一个已知的确定的目录去寻找引用的 程序集。
2.GAC的内部结构
GAC是一个特殊的结构化的目录,用Windows Explorer浏览你会以为它只是一个包含很多程序 集的普通目录。其实不是这样的,在命令行下查看,你会发现它实际上包含很多子目录,子目录 的名字和程序集的名称是相同的,但它们都不是实际的程序集,实际的程序集位于程序集名对应 的目录下。比如进入GCFWK子目录,我们会发现其中又有很多的子目录。机器内每一个安装到GAC 的GCFWK.dll在GCFWK中都会有一个子目录。这里只 有一个目录表明只有一个版本的GCFWK程序集被安装。实际的程序集保存在每一个对应的版本目录下。目录的名称以下划线的形式分割为“(Version)_(Culture)_(PublicKeyToken)”。GCFWK的语言文化信息为netture,就表示为0.0.0__bf5779af662fc055”。 表示得意义是:
“GCFWK, Version=1.0.0.0, Culture=neutral,PublicKeyToken=bf5779af662fc055” 如果语言文化信息为”ja”,就表示”1.0.0.0_ja_bf5779af662fc055”表示得意义是: “GCFWK, Version=1.0.0.0, Culture=ja,PublicKeyToken=bf5779af662fc055”
生成强命名程序集
1.生成密钥
运行Visual Studio .NET 2013 命令提示行
输入:存放密钥的路径>sn -k 密钥文件名
例如:D:\>sn -k mykey.key
然后用-tp参数查看:SN –tp mykey.PublicKeys
2.使用密钥
把密钥文件放到解决方案的根目录下,打开解决方案,修改要强命名项目的AssemblyInfo.cs文件
[assembly: AssemblyVersion("1.0.0.1")] //强命名程序集一般都指定版本号
[assembly: AssemblyDelaySign(false)] //是否要延迟签名 false:不延迟签名 true:延迟签名
[assembly: AssemblyKeyFile("mykey.key")] //密钥文件的路径
3.生成强名称程序集
编译解决方案,这样生成的程序集就是强命名的程序集了
4.部署强命名程序集到GAC中
运行Visual Studio .NET 2013 命令提示行
输入:任意路径>gacutil /i 强命名程序所在的绝对路径
例如:D:\>gacutil /i E:\我的默认网站\myweb\myAssembly.dll
注意:只有强命名的程序集才可以部署到GAC中(GAC:全局程序集缓冲)
常见问题
1.强命名程序集引用弱命名程序集,编译报错
在PetShop4程序中加入了一个业务外观层,然后在业务逻辑层(PetShop.BLL)引用这个程序集,点“生成”,出现以下的错误:“程序集生成失败 -- 引用的程序集没有强名称”,原因是PetShop.BLL是强命名程序集,强命名程序集不能用普通
程序集造成的。
解决方法:
首先打开visual studio 2008命令提示(开始-->程序-->microsoft visual studio 2008-->visual studio tools-->visual studio2008 命令提示),在其中输入:sn -k PetShop.IBLL.snk回车,这样就生成了 PetShop.IBLL.snk,在路径C:\Program Files\Microsoft Visual Studio 9.0\VC找到 PetShop.IBLL.snk文件,放在IBLL项目的根目录也就是IBLL目录下。
然后打开BLL项目的AssemblyInfo.cs,在里面加入如下代码行:[assembly: AssemblyKeyFile("PetSHop.IBLL.snk")]。
然后重新生成PetShop.IBLL项目,这样一个强命名的程序集就生成了。