在我们为程序集写单元测试的时候,经常遇到一个问题:用于写单元测试代码的程序集不能直接访问被测试程序集中的 internal 类型和成员。一般这时我们都用反射的方法,但是这却是效率不高,很费时费力的:(
在 .NET Framework 2.0 中出现了一个新的东西叫做“Friend Assemblies”(友元程序集)。这个东东和 C++ 中的 friend 比较类似。在 .NET 中,通过友元程序集的方式可以让 internal 的类型或者方法等被其他的 assembly 访问(private 是仍然不能被访问的)。 有了所谓的“Friend Assembly”,对我们写单元测试可方便得多了(什么MS再搞出个“Family Assembly”可以直接访问 private 那就更爽了,呵呵)。 比如我们有两个程序集 System.Xml.dll 和 System.Data.SqlXml.dll。如果要让 System.Xml 能够访问 System.Data.SqlXml 中的 internal 内容,我们可以在 System.Data.SqlXml 中使用 InternalsVisibleToAttribute 属性:
[assembly: InternalsVisibleTo("System.Xml")]
如果 System.Xml 有强名称的话,在 InternalsVisibleTo 中还要写上 PublicKey 属性。比如:
[assembly: InternalsVisibleTo("System.Xml, PublicKey=0024000004800000940000000602.....")]
一般的,PublicKey 属性的内容会很长(我这边用的都是320个字符——160字节)。有两个方法可以获取这个 PublicKey(使用强名称工具sn.exe):
-
直接从编译好的 System.Xml.dll 中获取(当然这时还没有使用到 System.Data.SqlXml 中的内部成员和类型什么的了):
sn.exe -Tp System.Xml.dll -
从给 System.Xml 签名的 keyfile 中读取:
sn.exe -p KeyFile.snk temp.pk // 将 public key 从 KeyFile.snk 写到 temp.pk 中
sn.exe -tp temp.pk // 显示 public key
有关这方面的详细信息,可以查看下面这两个网页。或者 google 一下:
- Strong Name Tool: http://msdn2.microsoft.com/en-us/library/k5b5tt23(VS.80).aspx
- Friend Assemblies: http://msdn2.microsoft.com/en-us/library/0tke9fxk(vs.80).aspx