2013-03-14 29 views
0

我正在爲自動化調度程序編寫一個插件體系結構,它需要健壯,所以我試圖做ASP.NET/IIS風格的AppDomains - 即每個AppDomain是真的被視爲它們自己獨特的應用程序,它們之間沒有共享對象。完整的ASP.NET風格的AppDomain程序集隔離

我在AppDomainSetup中設置ApplicationBase,ConfigurationFileShadowCopyFiles

自動化調度程序中有一個常見的程序集,我爲每個插件加載 - 它處理加載插件的主程序集,捕獲未捕獲的異常和記錄。有跡象表明,我已經確定這種方法也有一些不足:

  • 通過設置ApplicationBase到插件存儲在何處,共同的組件(駐留在不同的路徑)的任何依賴關係將不再得到解決。我通過掛鉤AssemblyResolve事件破壞了這個工作,但這導致了其他問題。

  • 普通程序集和插件都有可能引用他們自己的同名命令程序集的副本 - 可能每個程序集都有不同的版本。或者也許是一個名稱相同但內容完全不同的程序集。覆蓋AssemblyResolve,插件的副本將始終首先加載。

  • 不是真的擔心這個問題,但從安全角度來看,我認識到插件可能會重寫調度器的依賴關係,導致它執行某些惡意的事情,或者反映到常見的程序集中並獲取內部消息。

所以我決定,也許正確地做到這一點的唯一方法是根本就沒有做到這一點 - 強制清潔的分離,任何組件不能加載到AppDomain中。我不確定要做什麼最好的方法是什麼,或者即使這是最好的方法。

您認爲如何?

回答

0

我不確定這是否完全回答你的問題,但我們有一個類似的應用程序設置,我們有獨立的子AppDomain和一個共享DLL文件夾,並且我們成功地使用了AssemblyResolve。

我們的文件結構爲:

[PathToApplication]\OurApplication.exe 
[PathToApplication]\AddIns\[SharedAssemblies]\*.dll 
[PathToApplication]\AddIns\[FirstAddIn]\*.dll 
[PathToApplication]\AddIns\[SecondAddIn]\*.dll 

凡在方括號中的部分由實際路徑替換。

在我們的例子中,共享程序集也是由主AppDomain加載的,所以我們在主要的App.config中設置如下。

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <probing privatePath="AddIns\[SharedAssemblies]" /> 
    </assemblyBinding> 
</runtime> 

確保共享組件不沿着主可執行文件存在,或者它會從那裏,而不是加載它們,並默默地將停止DLL文件正在內存共享所有的應用程序域之間。

然後,對於每個加載項的AppDomain,我們對其進行了配置,使得基本路徑位於加載項文件夾和共享文件夾之上的文件夾,並設置了私有bin路徑,以便搜索了正確的子文件夾正確的順序:

var basePath = @"[PathToApplication]\AddIns"; 

var configFile = Path.Combine(
     basePath, 
     addInFolder, 
     addInAssemblyName + ".dll.config"); 

var binPaths = new [] { "[SharedAssemblyFolder]", addInFolder }; 

setup = new AppDomainSetup 
{ 
    ApplicationBase = basePath, 
    ConfigurationFile = configFile, 
    LoaderOptimization = LoaderOptimization.MultiDomain, 
    PrivateBinPath = string.Join(";", binPaths), 
    PrivateBinPathProbe = string.Empty, 
}; 

這樣,它始終搜索共享文件夾第一,所以即使外接提供了它會被忽略的同名自己的DLL。

我們在應用程序入口點上設置了[System.LoaderOptimization(LoaderOptimization.MultiDomain)]並驗證了這些DLL實際上在內存中共享(很容易讓它稍微錯誤並且默默停止這種情況發生)。

希望這有助於某種方式。