无需设置强签名分离NUnit测试DLL和主程序集的方法

.NET 2.0中友元程序集(Friend Assemblies)功能对于单元测试来说非常有用,通过这一功能可以分离测试代码和主程序的实际功能代码,但MSDN上的文档将通过InternalsVisibleToAttribute建立友元程序集和强签名(Strong Name)放在一起说明,其实这是两个功能是没有相互关联的。

强签名是为了保证发布的程序集唯一性,从而保证不被冒用和篡改。友元程序集则允许指定的程序集可以访问具有特定InternalsVisibleToAttribute属性程序集的internal修饰的接口和类,这相当于在主程序集上开了一个后门,只有指定的单元测试Test.DLL能够访问内部功能。

其实,分离测试和程序集只需在主程序集中声明InternalsVisibleToAttribute属性即可,一般在AssemblyInfo.cs上插入这一属性:

[assembly: InternalsVisibleToAttribute("TSE.DESE.Test")]

这样就允许程序集TSE.DESE的单元测试DLL,程序集的名称(查看方法:项目->属性->应用程序->程序集名称)为TSE.DESE.Test访问TSE.DESE主程序集的internal内部类和接口。

以上设置虽然方便,但是,如果发布TSE.DESE的话,.NET将允许任何程序集名称为“TSE.DESE.Test”访问TSE.DESE的内部,这是一个不大不小的后门,所以最好将上述语句用C#的预处理语句包裹起来,变成:

#if DEBUG
[assembly: InternalsVisibleToAttribute(
"TSE.DESE.Test")]
#endif

这样,当选择Release时,主程序集也就没有了InternalsVisibleToAttribute属性,从而保证了的安全性,当然,此时Release编译的TSE.DESE.Test也将出错,所以应该在Release编译时跳过生成程序集TSE.DESE.Test。

当然这一方法的安全性不如MSDN上方法,但起码非常方便,也不用通过一系列sn命令获得非常长的PublicKey。

PS:MSDN的InternalsVisibleToAttribute构造函数文档有错误,PublicKey不是PublicKeyToken,因此下面的示例是错误的:

[assembly:InternalsVisibleToAttribute("AssemblyB, PublicKey=32ab4ba45e0a69a1")]
正确的应该形如:
[assembly:InternalsVisibleTo("cs_friend_assemblies_4, PublicKey=002400000480
0000940000000602000000240000525341310004000001000100031d7b6f3abc16c7de526fd6
7ec2926fe68ed2f9901afbc5f1b6b428bf6cd9086021a0b38b76bc340dc6ab27b65e4a593fa0
e60689ac98dd71a12248ca025751d135df7b98c5f9d09172f7b62dabdd302b2a1ae688731ff3
fc7a6ab9e8cf39fb73c60667e1b071ef7da5838dc009ae0119a9cbff2c581fc0f2d966b77114
b2c4
")]

2007年3月29号补充:

即使不应用程序集签名,还是需要在被测试的主程序集上注释掉下列三行,原因不明,也许是微软出品的又一个bug,可能和VS.NET 2005 SP1相关

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
//[assembly: AssemblyKeyName("")]

posted @ 2006-05-11 16:47  丁丁  阅读(1410)  评论(5编辑  收藏  举报