首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

C# 組件與反射實戰:Assembly 載入、類型發現、動態實例化與插件化架構基礎

     編輯:Java 相關知識

在 .NET 生態中,Assembly (組件) 是部署、版本控制、安全權限、類型邊界的基本單元。反射 是運行時檢查組件中繼數據、動態操作類型的核心技術,支撐插件架構、依賴注入、序列化、ORM 等基礎設施。

組件核心概念

  • 物理形式:.exe (可執行) 或 .dll (類庫)。
  • 邏輯構成:清單 (元數據:名稱、版本、文化、公鑰、文件列表、類型導出) + 類型元數據 + IL 代碼 + 資源。
  • 版本號:Major.Minor.Build.Revision,強名稱組件簽名確保唯一性。

AssemblyInfo.cs 核心屬性


[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

反射核心 API (System.Reflection)

核心類職責高頻方法
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();
    }
}

插件化架構基礎模式

  1. 定義公共契約接口 IPlugin (放在獨立 Contract 組件)。
  2. 插件組件實現 IPlugin,編譯為 DLL 放入 plugins/ 目錄。
  3. 宿主掃描目錄,Assembly.LoadFrom 加載,GetTypes() 篩選實現 IPlugin 的類型。
  4. Activator.CreateInstance 實例化,調用 Initialize() / Execute()。
  5. 進階:AssemblyLoadContext (Core 3.0+) 實現插件隔離卸載、依賴版本隔離。

性能優化建議

  • 緩存 Type, MethodInfo, PropertyInfo 對象 (反射開銷大)。
  • 高頻調用改用 Delegate.CreateDelegate 或 Expression Tree 編譯為委託 (接近直接調用速度)。
  • 源生成器 替代運行時反射 (C# 9+,編譯期生成代碼,零反射開銷)。

反射賦予 .NET 極致動態能力,但「大權在手,責任在肩」。插件架構、框架開發請建立反射邊界層,業務代碼盡量靜態類型安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved