2010-10-15 52 views
6

我有一個使用BinaryFormatter反序列化對象的VS加載項。爲了解決這個對象的類型,它調用Assembly.Load(objectTypeFullName),但是它觸發了一個異常,因爲Assembly.Load在它搜索的任何地方都找不到它。給定的程序集是加載宏程序集的兄弟,但似乎Assembly.Load()在那裏找不到它。如何確定Assembly.Load()在哪裏搜索程序集?

一個可能的解決方案是確定Assembly.Load應該在哪裏查找程序集。

我該怎麼辦? PS:我想不把這個程序集放在GAC上,因爲每次我重新編譯程序集時都需要更新它。

回答

4

您可以使用AppDomainSetup.PrivateBinPath來添加其他私人搜索路徑。這可以通過AppDomain.SetupInformation檢索。

另一種選擇是訂閱AppDomain.AssemblyResolve以覆蓋無法找到裝配體時的行爲。

+0

謝謝里德。一些注意事項:即使AppDomain.AppendPrivatePath已被棄用,以支持AppDomainSetup.PrivateBinPath,我只能使用第一個。修改後,AppDomainSetup.PrivateBinPath保持爲空。 AppDomain.AppendPrivatePath允許我添加任何路徑,它是AppDomain.BaseDirectory的子項,在很多情況下這是足夠的,不是我的,因爲我的BaseDirectory是DevEnv目錄。另一種解決方案,AppDomain.AssemblyResolve就夠用了。注意事件僅在.NET無法自行解析程序集時調用。如果所有處理程序都返回null,則拋出異常 – 2010-10-17 12:07:09

3

如果您只是試圖確定程序集加載程序試圖從何處加載DLL,我建議您打開融合日誌。這樣做將使您能夠獲得輸出結果,以顯示爲相應的dll檢查的每個路徑。

有關於如何配置融合日誌的MSDN article以及關於如何調試加載失敗的Suzanne Cook有用的文章。如果打開LogFailures,並且只能獲取未能加載的程序集的輸出。

+0

非常有趣的是這個融合日誌,我正在閱讀這篇文章。謝謝。 – 2010-10-17 12:02:04

4

這裏是展示AssemblyResolve如何可能被用來解決您的組件(如每裏德Copey的答案)的代碼片段:

// register to listen to all assembly resolving attempts: 
AppDomain currentDomain = AppDomain.CurrentDomain; 
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 


// Check whether the desired assembly is already loaded 
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) { 
    string desiredAssmebly = args.Name; 
    if (desiredAssembly.Equals("NameUsedToLoadMyAssembly")){ 
     return Assembly.LoadFrom(myAssemblyPath); 
    } 

    return null; 
    } 

此外,注意,AssemblyResolve的MSDN頁指出:

從.NET Framework 版本4開始, ResolveEventArgs.RequestingAssembly 屬性返回裝配,即 請求的裝配加載可能爲 無法解析...

如果知道程序集相對於請求程序集的位置,可以使用此方法。

+0

赫爾希,謝謝+1。事實上,你的解決方案竟然是我使用的解決方案,並且我最終使用了你的代碼片段。我將裏德的答案標記爲接受,因爲它更完整。不管怎樣,謝謝你。 – 2010-10-17 12:09:57