2012-06-06 62 views
3

在處理插件程序集的子目錄時,存在一個衆所周知的問題,即一旦它們嘗試從其子目錄加載它們各自的依賴項,這些程序集就無法加載。一種解決方案是在初始化時在AppDomain中加載其PrivateBinPath設置在它們的AppDomainSetup對象中的插件。但是,這會導致關於編組/跨AppDomain通信的其他困難,特別是如果插件應該提供一些GUI。插件AppDomains解決方法

當安全性方面的優先級較低(非關鍵性的實用程序應用程序,由於錯誤的插件導致崩潰時沒有嚴重問題),我有以下想法:在應用程序啓動時,應該搜索所有插件目錄,並且應該創建一個新的AppDomain,它的bin路徑中包含這些目錄。然後,整個應用程序及其GUI在新的AppDomain中運行,以及所有插件。

在特定情況下,是否有任何理由避免該解決方案?或者有什麼理由可以解釋爲什麼這個解決方案不可行?

+0

我認爲,如果你的主界面在相同的AppDomain作爲插件運行,如果插件崩潰,主UI可能會崩潰。你使用插件框架還是「RYO」? – IAbstract

+0

@IAbstract:即使在另一個AppDomain中運行,也不要崩潰插件通常也會導致主UI失敗?畢竟,插件中引發的任何異常都會跨AppDomain邊界進行編組,並使主應用程序退出,除非我處理異常。在我的特殊情況下,這是RYO - 我研究了Addin框架並閱讀了許多關於它的文章,但它們都提到了核心應用程序和插件之間極簡主義的界面,而不是複雜和深層嵌套的對象層次結構。需要轉移。 –

回答

1

考慮到您描述的情況,我不知道與您的第二個域的提案相關的任何問題。但是,您也可以通過使用Assembly.LoadFrom搜索addins子目錄並從那裏加載程序集來調查在初始域上處理程序集加載失敗的可能性。一個可能的設置對於這一點,在FindAssemblyByName就必須實現通過所有可能的地點進行搜索的

例子:

static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; 

    // ... 
} 

static Assembly CurrentDomain_AssemblyResolve(
    object sender, 
    ResolveEventArgs e) 
{ 
    var assemblyName = new AssemblyName(e.Name); 

    string assemblyFilePath = FindAssemblyByName(assemblyName); 

    if (string.IsNullOrEmpty(assemblyFilePath)) 
     return null; 

    return Assembly.LoadFrom(assemblyFilePath); 
} 
+0

這隻適用於託管程序集嗎?更具體地說,當我手動在子目錄中找到插件程序集時,會自動發現相同子目錄中的非託管程序庫? –

+0

'Assembly.LoadFrom'允許找到並加載該路徑的進一步依賴關係,因爲路徑信息由上下文維護。但是,對於混音中的非託管程序集,我不太樂意給你任何確定性。 –

+0

我對此進行了進一步的閱讀並做了一些測試。看起來確實好像不僅是託管的,而且如果它們與加載了'LoadFrom'的程序集位於相同的目錄中,則會發現非託管庫。但是,閱讀[docs](http://msdn.microsoft.com/en-us/library/1009fa28.aspx),似乎'LoadFrom'專門將程序集加載到所謂的* load-from *上下文中,而* load *上下文由於各種原因將是優選的。另一方面,我沒有看到任何方式從自定義位置將程序集加載到* load *上下文中。 –