根据How the Runtime Locates Assemblies第2步是Checking for Previously Referenced Assemblies。AppDomain.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步不起作用。
谢谢。
谢谢。这解决了我的问题。在我看来,上述原始帖子中的“解决方案”实际上是一个体面的例子。程序集被加载到LoadFrom上下文中,而不是Load上下文中。所以刚刚从AssemblyResolve中返回它是一个体面的解决方案,并将其转移到Load上下文中。 – 2010-02-03 20:24:38
我完全同意 - 'AssemblyResolve'是一个非常好的解决方案。 (事实上,我正在更新我的答案,以便在您离开此评论时确切地说出。):) – 2010-02-03 20:35:08