2010-02-03 76 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将程序集加载到“既不是上下文”中。

相关问题