在 .NET 生態中,Assembly (組件) 是部署、版本控制、安全權限、類型邊界的基本單元。反射 是運行時檢查組件中繼數據、動態操作類型的核心技術,支撐插件架構、依賴注入、序列化、ORM 等基礎設施。
.exe (可執行) 或 .dll (類庫)。Major.Minor.Build.Revision,強名稱組件簽名確保唯一性。
[assembly: AssemblyTitle("MyLib")]
[assembly: AssemblyVersion("1.0.0.0")] // 運行時版本策略依賴此
[assembly: AssemblyFileVersion("1.0.0.0")] // 文件系統版本
[assembly: AssemblyInformationalVersion("1.0.0-beta")] // 產品版本 (NuGet 顯示)
[assembly: ComVisible(false)] // COM 互操作可見性
[assembly: Guid("...")] // 類型庫 ID
| 核心類 | 職責 | 高頻方法 |
|---|---|---|
Assembly | 組件級操作 | Load(), LoadFrom(), GetTypes(), GetManifestResourceStream() |
Type | 類型描述 (核心) | GetMethods(), GetProperties(), GetConstructors(), GetCustomAttributes(), IsAssignableFrom() |
MethodInfo | 方法元數據 | Invoke(obj, params), GetParameters(), ReturnType |
PropertyInfo | 屬性元數據 | GetValue(obj), SetValue(obj, val) |
ConstructorInfo | 構造器元數據 | Invoke(params) |
FieldInfo | 字段元數據 | GetValue(obj), SetValue(obj, val) |
// 1. 加載組件 (三種方式)
Assembly asm = Assembly.Load("MyAssembly"); // 從 GAC/探測路徑加載 (推薦)
Assembly asm = Assembly.LoadFrom(@"C:\path\MyAssembly.dll"); // 從路徑加載 (上下文不同)
Assembly asm = Assembly.LoadFile(@"C:\path\MyAssembly.dll"); // 純文件加載 (無依賴解析)
// 2. 獲取類型
Type personType = asm.GetType("MyAssembly.Person"); // 大小寫敏感
// 3. 創建實例 (多種方式)
object person = Activator.CreateInstance(personType); // 無參構造
object person = Activator.CreateInstance(personType, "張三", 25, "男"); // 有參構造
// 或獲取構造器
ConstructorInfo ctor = personType.GetConstructor(new[] { typeof(string), typeof(int), typeof(string) });
object person = ctor.Invoke(new object[] { "李四", 30, "女" });
// 4. 調用方法/屬性
MethodInfo sayHi = personType.GetMethod("SayHi");
sayHi.Invoke(person, null);
PropertyInfo nameProp = personType.GetProperty("Name");
nameProp.SetValue(person, "王五");
string name = (string)nameProp.GetValue(person);
// 組件內嵌資源
using (Stream stream = asm.GetManifestResourceStream("MyAssembly.config.json")) {
using (StreamReader reader = new StreamReader(stream)) {
string json = reader.ReadToEnd();
}
}
IPlugin (放在獨立 Contract 組件)。IPlugin,編譯為 DLL 放入 plugins/ 目錄。Assembly.LoadFrom 加載,GetTypes() 篩選實現 IPlugin 的類型。Activator.CreateInstance 實例化,調用 Initialize() / Execute()。AssemblyLoadContext (Core 3.0+) 實現插件隔離卸載、依賴版本隔離。Type, MethodInfo, PropertyInfo 對象 (反射開銷大)。Delegate.CreateDelegate 或 Expression Tree 編譯為委託 (接近直接調用速度)。反射賦予 .NET 極致動態能力,但「大權在手,責任在肩」。插件架構、框架開發請建立反射邊界層,業務代碼盡量靜態類型安全。