Dot-Net
強大的外掛/外掛管理的良好架構/庫
我們有一個應用程序,作為其要求之一,它將採用任意 3rd 方外掛,載入它們,並與我們自己開發的應用程序一起執行它們的 UI。我們一直在將這些 3rd 方外掛載入到他們自己的 AppDomain 中以進行隔離,一切正常。
直到其中一個外掛因未處理的異常而崩潰。在這種情況下,整個應用程序都會崩潰,即使真正受到影響的只是我們的“額外”工具視窗之一。
理想情況下,我們希望通過某種方式來處理“未處理”異常,解除安裝損壞的 AppDomain,然後重新載入它。 問題是我們在事件處理程序中找不到未處理異常的機制,我們可以將異常標記為“已處理”。此外,由於外掛有自己的 UI 組件和自己的使用者互動集,因此很難將我們與外掛的互動“包裝”在 try/catch/finally 塊中。
是否有任何框架/程式庫/模式可以解決這個問題?我們可以很好地做外掛; 我們需要幫助的是當不同 AppDomain 中的程式碼意外失敗時保持應用程序處於活動狀態。
您可以使用
System.Addin框架(有時稱為MAF),正確設置有點麻煩,但它旨在提供隔離(崩潰保護)。System.Addin基於遠端處理。使用這個框架,您可以讓外掛在同一個程序、另一個應用程序域甚至另一個程序中以有限的權限執行。如果您需要全面的崩潰保護,您可能需要使用程序分離選項。不過,它可能會以性能為代價。
您可以使用此程式碼在不同的應用程序域中載入外掛:
AppDomain addInDomain = AppDomain.CreateDomain("addin domain"); // addInDomain.PermissionSet = ... AddInEnvironment env = new AddInEnvironment(addInDomain); // Activate the add-in IHostView addinInstance = addinToken.Activate<IHostView>(env); Console.WriteLine(addinInstance.DoSomething()); AppDomain.Unload(addInDomain);如果要將外掛載入到另一個程序中,以實現完全隔離:
AddInProcess process = new AddInProcess(); process.Start(); // Activate the add-in IHostView addinInstance = addinToken.Activate<IHostView>(process, AddInSecurityLevel.Internet); try { // use a catch block, prevent exceptions from the addin crashing the main app Console.WriteLine(addinInstance.DoSomething()); } catch (Exception e) { Console.WriteLine(e); } process.Shutdown();這個部落格很好地描述了這個設置。
可以
System.Addin與 MEF 結合使用,這些是免費的工具包,請參閱本文。請注意,System.Addin 模型可能提供崩潰保護,您仍然需要處理外掛程式碼中的減速或死鎖。非同步使用在這裡會有所幫助。