項目開發的過程當中,調試使用的多是最多的操做。任何代碼寫出來都須要通過調試和整合,以此擴展和提高程序的穩定性和可靠性。談到.NET的單元測試,在這裏就得提提.NET的友元程序集這一特性,也借用.NET進行單元測試的一個較爲好用的.NET屬性,來說解一下程序集、定製Attribute的相關知識。一些知識須要反覆的去品味和反思,不要以爲你會了就不在乎,等你在乎的時候,你就有些力不從心的意思了。安全
生活在於不停的折騰,只有通過磨練,纔可知什麼時候須要安分,什麼時候須要挑戰。函數
毒雞湯喝完了,來聊聊正事...單元測試
本文主要是談論「友元程序集」的一些知識,既然是作一個解析,那麼就應該把一些知識作一個展開來論述。在這裏先談談程序集(有人以爲很瞭解,有人以爲徹底不懂,狀況不一樣,選擇不一樣,需者自取吧),接下來咱們具體的看看程序集這一特性。測試
程序集是一個或多個模塊/資源文件的邏輯分組,程序集是重用、安全性以及版本控制的最小單元。對於程序集的結構有以下圖。this
對於程序集的組成就不一一作解析,在這裏就單獨談談元數據這一結構。元數據是一個二進制數據塊,由一組數據表,元數據老是與包含IL代碼的文件關聯,元數據由幾個表構成。元數據的做用有上圖介紹。元數據的表有三個類別:定義表,引用表,清單表。對於這些表的結構在這裏就不作介紹了,有興趣的能夠搜索一下,我的認爲元數據這一結構應該好好的研究一下。spa
上面的論述中簡單的介紹了程序集的結構和元數據,在這裏簡單的介紹一下定製Attribute這一.NET的特性。定製Attribute容許定義的信息應用於幾乎每個元數據表記錄項,這種可擴展的元數據信息能在運行時查詢,從而動態改變代碼的執行方式。在C#種,爲了將一個定製Attribute應用於一個目標元素,須要將Attribute放置於目標元素前面的一對方括號中。版本控制
CLR容許將定製Attribute應用於可在文件的元數據中表示的幾乎全部元素。定製Attribute主要應用於程序集、模塊、類型、字段、方法、方法參數、方法返回值、屬性、事件、泛型類型參數。attribute是類的一個實例,將一個attribute應用於一個目標元素時,語法相似於調用類的某個實例構造函數。定製Attribute的實例以下:調試
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
上面代碼取自InternalsVisibleToAttribute類中,該類是完成友元程序集特性的核心對象,下面會作一個具體的介紹。AttributeUsage須要接受一個AttributeTargets枚舉類型的值做爲參數,稱之爲定位參數,是強制性的,必須指定。AllowMultiple參數用於獲取或設置一個布爾值,指示是否有多個實例指定的屬性能夠爲單個程序元素指定。Inherited參數用於獲取或設置一個布爾值,指示指定的屬性是否能夠繼承由派生類和重寫成員。code
定製Attribute能夠應用於單個目標元素,定製Attribute的順序是可有可無的。在C#種,可將每一個Attribute都封閉到一對方括號中,也能夠在一對方括號中封閉多個以逗號分隔的Attribute。對象
定製Attribute就是一個類的實例,它被序列化成駐留在元數據中的一個字節流,在運行時,能夠對元數據中包含的字節進行反序列化,從而構造類的一個實例。
扯了半天,終於到講解「友元程序集」這一個概念,「友元程序集」在.NET2中提出,使用InternalsVisibleToAttribute來實現這一特性,InternalsVisibleTo只能用於程序集,而且你能夠在同一個程序集種應用屢次。源程序集:包含這個屬性的程序集。友元程序集可以看到源程序集的全部內部成員,相似於公有的。
友元程序集實例介紹:
//AssemblySource.DLL [assembly: InternalsVisibleTo(DotNetShare)] public class AssemblySource { public static void Share(); } //DotNetShare.DLL public class DotNetShare { private static void Main() { AssemblySource.Share(); } }
AssemblySource.DLL和DotNetShare.DLL之間存在一種特殊的關係,可是這種關係只能單項操做。接下來看一下InternalsVisibleToAttribute的實現源碼。InternalsVisibleToAttribute繼承自Attribute類,該類指定一般僅在當前程序集中可見的類型對指定程序集可見。該類包含兩個屬性和一個方法。
1.AssemblyName
public string AssemblyName { [__DynamicallyInvokable] get { return this._assemblyName; } }
該屬性爲一個只讀屬性,一個表示友元程序集名稱的字符串。該屬性用於獲取友元程序集的名稱,採用 internal 關鍵字標記的全部類型和類型成員對該程序集均爲可見。
2.InternalsVisibleToAttribute()
public InternalsVisibleToAttribute(string assemblyName) { this._assemblyName = assemblyName; }
該方法爲一個構造函數,用指定的友元程序集的名稱初始化 <see cref="T:System.Runtime.CompilerServices.InternalsVisibleToAttribute"/> 類的新實例。接收一個友元程序集的名稱。
對於友元程序集有一個約束,若是一個友元程序集是簽名的,那麼源程序集爲了保證信任正確的代碼,就須要指定友元程序集的公鑰。
對於本文主要是在介紹友元程序集這一特性,順帶介紹程序集和定製Attribute這兩個特性,方便你們理解友元程序集這一特性。這篇文章但願對你們有所幫助,仍是那句話,需者自取,也虛心接受吐槽。知識在於分享,更在於每個人的思考。