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

插件式框架探索:應用程式域(AppDomain)隔離與動態載入

     編輯:關於.NET

前言

應用程式域(AppDomain)是 .NET 執行環境的核心隔離單位。一個進程可容納多個 AppDomain,各自擁有獨立的記憶體、型別系統與安全策略,實現「進程內隔離」。本文深入探討 AppDomain 在插件框架中的應用:建立與卸載、載入優化、異常隔離、跨域 UI 組合。

一、 AppDomain 核心優勢

  • 異常隔離:單一域內未處理例外不會摧毀其他域或主進程。
  • 動態載入/卸載組件:突破 .NET「組件一旦載入無法卸載」的限制,透過卸載整個 AppDomain 釋放所有組件。
  • 獨立安全與配置策略:可為每個域指定權限集合與配置檔。
  • 執行緒無關性:多執行緒可自由跨域執行,無一對一綁定關係。

二、 建立、執行與卸載 AppDomain

// 建立新域
AppDomain domain = AppDomain.CreateDomain("Plugin Domain");

// 在新域執行程式碼
domain.DoCallBack(new CrossAppDomainDelegate(() =>
{
    Window win = new Window
    {
        Width = 300,
        Height = 100,
        Content = AppDomain.CurrentDomain.FriendlyName
    };
    win.Show();
}));

// 卸載域(釋放所有資源)
AppDomain.Unload(domain);

三、 載入優化:LoaderOptimization

預設每個 AppDomain 獨立載入參考組件,造成效能損耗。透過 LoaderOptimization 屬性可啟用「域中立組件」共享:

[STAThread]
[LoaderOptimization(LoaderOptimization.MultiDomainHost)]
public static void Main()
{
    App app = new App();
    app.InitializeComponent();
    app.Run();
}

三種模式:SingleDomain(預設)、MultiDomain(所有組件共享)、MultiDomainHost(僅強名稱組件共享)。插件框架建議使用 MultiDomainHost 平衡隔離與效能。

四、 異常隔離實戰

新域內的未處理例外會冒泡至預設域導致進程崩潰。解決方案:在主域註冊 Dispatcher.UnhandledException,標記 Handled = true 並主動卸載故障域:

AppDomain domain = AppDomain.CreateDomain("Plugin Domain");
Dispatcher.CurrentDispatcher.UnhandledException += (s, e) =>
{
    e.Handled = true;
    MessageBox.Show(e.Exception.Message);
    AppDomain.Unload(domain); // 隔離故障,主域存活
};

domain.DoCallBack(new CrossAppDomainDelegate(() =>
{
    Window win = new Window { ... };
    win.Loaded += (o, a) => throw new Exception("Plugin crash!");
    win.Show();
}));

五、 跨域 UI 組合:FrameworkElementAdapters

UI 元素無法跨域序列化傳遞。WPF Add-in 模型提供 FrameworkElementAdapters 透過視窗控制代碼(HWND)實現跨域視覺樹投影:

// 新域建立控件並轉換為合約
domain.DoCallBack(() =>
{
    Button btn = new Button { Content = "Cross Domain" };
    INativeHandleContract contract = FrameworkElementAdapters.ViewToContractAdapter(btn);
    AppDomain.CurrentDomain.SetData("pluginUI", contract);
});

// 主域取得合約並還原為 FrameworkElement
INativeHandleContract contract = domain.GetData("pluginUI") as INativeHandleContract;
FrameworkElement ui = FrameworkElementAdapters.ContractToViewAdapter(contract);
MainWindow.Content = ui; // 成功顯示來自其他域的 UI

此技術讓插件 UI 在獨立域運行,卻能無縫呈現於主應用程式視窗中。

結語

AppDomain 提供進程級隔離的輕量替代方案,是插件框架實現「故障隔離、熱插拔、權限沙箱」的關鍵基礎設施。結合載入優化、異常捕獲與跨域 UI 技術,可構建健壯、可擴充的插件生態系統。

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