在我們為程式集寫單元測試的時候,經常遇到一個問題:用於寫單元測試代碼的程式集不能直接存取被測試程式集中的 internal 類型和成員。一般這時我們都用反射的方法,但是這卻是效率不高,很費時費力的:(
在 .NET Framework 2.0 中出現了一個新的東西叫做“Friend Assemblies”(friend 組件)。這個東東和 C++ 中的 friend 比較類似。在 .NET 中,通過friend 組件的方式可以讓 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