2017-02-28 125 views
2

我有一個依賴於庫的可執行文件。我還有一個「加載器」應用程序,它將可執行文件加載到單獨的AppDomain(我的「沙箱」)中並在那裏運行它。該庫需要從沙箱外進行初始化,所以我需要在加載可執行文件之前加載庫。這按預期工作,但是當我現在加載可執行文件時,該庫會再次加載,並且可執行文件使用未初始化的副本。.net自動程序集解析加載重複程序集

Assembly.Load(File.ReadAllBytes(assemblyFile.FullName)); 

,而不是這樣的::

Assembly.LoadFrom(assemblyFile.FullName); 

但是,使用LoadFrom鎖定該文件

這隻有當我加載像這樣的庫中出現。我需要能夠刪除/寫入文件,因爲我的應用程序需要能夠重新加載整個沙箱及其中的所有程序集。

我也試過註冊AppDomain.AssemblyResolve,但如果它沒有找到該文件,這不正是我想要的它只是叫...

示例日誌輸出:

  • 加載庫X < - 手工負載
  • 初始化庫X
  • 加載可執行ý
  • 加載庫X < - 不好,我想用加載的X!

所以我的問題是:我如何強制.net使用已加載的程序集,而不是加載重複?

+0

是在同一個AppDomain中出現的兩個負載? –

+0

@DanField是的,我仔細檢查了這 – Whosdatdev

回答

0

我結束了我的修改沙箱的AppDomainSetup:

domainSetup.DisallowApplicationBaseProbing = true; 

現在,AssemblyResolve將被稱爲每次(無自動發現的組件)。現在,我可以從一個byte []加載組件並緩存(感謝@DanField誰建議緩存組件)

1

remarks on Assembly.Load(Byte[])

注意,此方法重載始終將創建自己的地圖新的裝配對象。

如果你想重新使用你的加載的程序集(無需額外的工作 - 框架不會自動爲你做)。

您也許可以在這裏使用Assembly.Load(string)Type.GetType(string)方法,但我懷疑這仍然會鎖定要修改的文件。我真的不確定如何在運行時修改這些文件,儘管如此 - 如果刪除或更改加載的程序集,預期的行爲是什麼?重新加載?將修改的代碼輸入到內存中?

您可能需要創建某種自己的程序集緩存機制。如果程序集不是那麼大,並且可以將它們放在內存中,它可能就像Dictionary<string, Assembly>一樣簡單 - 只需檢查字典在加載之前是否有裝配,否則使用Assembly.Load(Byte[])以您的方式加載現在。