2009-01-06 45 views
5

怪異的行爲組件的負荷時,混合使用Assembly.LoadFrom和Assembly.Load怪異的行爲混合使用Assembly.LoadFrom和Assembly.Load

組件的裝載時Assembly.LoadFrom加載程序集時我曾經遇到過一個怪異的行爲並在隨後的Assembly.Load上進行。
我使用Assembly.LoadFrom加載程序集,其中程序集位於不是執行文件夾的文件夾中。

後來在我的測試代碼中,當我嘗試再次使用Assembly.Load加載此程序集時,加載失敗,出現System.IO.FileNotFoundException(「無法加載文件或程序集...」),儘管程序集已經加載。加載失敗時使用強名稱和非強名稱(再次加載該程序集的原因是BinaryFormatter的用法)。

但是,如果程序集位於執行文件夾中,則兩種情況下的後期加載都會成功,並使用強名稱和非強名稱。在這種情況下,您可以看到兩個相同的組件從兩個不同的位置加載。

,再現此問題的一個簡單的碼樣本 -

大會assembly1 = Assembly.LoadFrom(@ 「C:\ A.DLL」);

//加載具有強名稱失敗 大會assembly2 = Assembly.Load(@ 「一個,版本= 1.0.0.0, 文化=中性公鑰= 14986c3f172d1c2c」);

//同時載入一個不強的失敗 Assembly assembly3 = Assembly.Load(@「a」);

  1. CLR忽略已加載程序集的任何說明?
  2. 任何想法我該如何緩解這個問題?

感謝。

回答

9

這並不奇怪。根據文檔,使用Load和LoadFrom加載會將程序集置於不同的上下文中。 This可能會有所幫助。

  1. CLR忽略已加載程序集的任何說明?

因爲它們處於不同的上下文中。

  1. 任何想法我該如何緩解這個問題?

從相同的上下文負載,或幫助CLR查找程序集,可能由一個處理器連接到AppDomain.AssemblyResolve

替代

如果是從加載組件的位置是的AppDomain下的子文件夾。BaseDirectory你可以一個條目簡單地添加到您的App.config:

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="bin;bin2\subbin;bin3"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

7

@Kent Boogart: 這似乎是正確的解釋。對於一個完整的解釋,蘇珊·庫克有這個博客帖子裏面詳細闡述比原來的你發佈多一點: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

以下是代碼利用AppDomain.AssemblyResolve -

// 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) { 
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
    foreach (Assembly assembly in assemblies) { 
     AssemblyName assemblyName = assembly.GetName(); 
     string desiredAssmebly = args.Name; 
     if (assemblyName.FullName == desiredAssmebly) { 
      return assembly; 
     } 
    } 

    // Failed to find the desired assembly 
    return null; 
}