2010-02-03 78 views
2

根據How the Runtime Locates Assemblies第2步是Checking for Previously Referenced AssembliesAppDomain.CreateInstance不遵循規則

但是,在下面的代碼中,您可以看到這絕對不會發生。在第一行中,一個程序集被加載(這應該使它成爲未來所有調用的「以前引用的程序集」。)

但是,當代碼調用AppDomain.CurrentDomain.CreateInstance時,AssemblyResolve事件表明運行時無法找到請求的程序集。

你可以告訴程序集被加載,因爲從AssemblyResolve事件我直接從CurrentDomain.GetAssemblies()返回程序集!

所以,顯而易見的問題是,爲什麼運行時沒有找到引用的程序集作爲「運行時定位程序集的方式」意味着第2步?

爲了運行此示例:創建一個新的控制檯應用程序,然後向該解決方案添加一個新的ClassLibrary,並將其保留爲ClassLibrary1。下面的代碼粘貼到控制檯應用程序的類節目:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Assembly asmbly = Assembly.LoadFile(Path.GetFullPath(@"..\..\..\ClassLibrary1\bin\Debug\ClassLibrary1.dll")); 
     Type firstType = asmbly.GetTypes().First(); 
     AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
     object myInstance = AppDomain.CurrentDomain.CreateInstance(asmbly.FullName, firstType.FullName); 
    } 

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     //WHY AM I HERE? 
     return AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(p => p.FullName == args.Name); 
    } 
} 

然後添加使用的參考,像這樣:

using System.Reflection; 
using System.IO; 

請注意,我特意將原來的路徑在這裏,使得運行時不會根據Step 4: Locating the Assembly through Codebases or Probing找到程序集我的方案是這樣的,我試圖故意使用Step 2中定義的功能。如果運行時可以通過步驟4找到路徑,那將正常工作。這是第2步不起作用。

謝謝。

回答

3

由於程序集加載到不同的上下文中 - LoadFile上下文,而AppDomain.CurrentDomain.CreateInstance嘗試使用Load上下文來解析程序集,所以無法解析。

從「瞭解情況」,在Understanding The CLR Binder

那麼,爲什麼CLR在首位裝載機 背景?裝載程序 上下文有助於確保裝入程序集時的加載順序爲 。 此外,它們提供了一種對組件及其依賴項的隔離度量,當它們被加載到 不同的上下文中時。

看起來你已經通過訂閱AssemblyResolve事件解決了這個問題,但也有可能會採取一些其他方法,根據您的要求:

+0

謝謝。這解決了我的問題。在我看來,上述原始帖子中的「解決方案」實際上是一個體面的例子。程序集被加載到LoadFrom上下文中,而不是Load上下文中。所以剛剛從AssemblyResolve中返回它是一個體面的解決方案,並將其轉移到Load上下文中。 – 2010-02-03 20:24:38

+0

我完全同意 - 'AssemblyResolve'是一個非常好的解決方案。 (事實上​​,我正在更新我的答案,以便在您離開此評論時確切地說出。):) – 2010-02-03 20:35:08

2

這是從MSDN

使用的LoadFile方法報價來加載和檢查具有相同的身份,但位於不同的路徑集。與LoadFrom方法一樣,LoadFile不會將文件加載到LoadFrom上下文中,也不會使用加載路徑解析依賴項。 LoadFile在這個有限的場景中很有用,因爲LoadFrom不能用於加載具有相同身份但路徑不同的程序集;它只會加載第一個這樣的程序集。

下面是一個很好的article詳細介紹了用於加載程序集的方法如何影響引用分辨率。

特別是這篇文章指出LoadFile將程序集加載到「既不是上下文」中。

相關問題