如何在 AssemblyResolve 事件之前在运行时加载程序集? [英] Howto load assemby at runtime before AssemblyResolve event?

查看:31
本文介绍了如何在 AssemblyResolve 事件之前在运行时加载程序集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实际上,我试图在我的解决方案中实现某种静态链接"程序集.所以我尝试了以下方法:

Actually i tried to implement some kind of 'statically linked' assemblies, within my solution. So i tried the following:

  • 使用 CopyLocal = false 添加对我的程序集的引用
  • 使用添加为链接"将 .dll 文件本身添加到我的解决方案中
  • 使用添加资源"-添加现有文件"将 .dll 文件本身添加到我的资源中
  • 从我的程序集中添加一些类型到 Form1 作为 private MyObject temp = new MyObject();

在这些步骤之后,我按预期得到了 FileNotFoundException.因此,让我们尝试使用此快速技巧在 AssemblyResolveEvent 中加载程序集

After these steps i got the FileNotFoundException as expected. So let's try to load the assembly within the AssemblyResolveEvent with this quick hack

AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
    {
        Assembly MyAssembly = AppDomain.CurrentDomain.Load(Properties.Resources.ExternalAssembly);
        return MyAssembly;
    };

所以这有效!我可以从 AssemblyResolveEvent 中的资源文件加载我的程序集.但是这个事件只会发生,如果它在其他任何地方都找不到我的程序集.但是我怎样才能之前加载我的程序集?.Net尝试搜索不同的地方?

So this works! I'm able to load my assembly from a resource file within a AssemblyResolveEvent. But this event only happens, if it couldn't find my assembly anywhere else. But how can i get my assembly be loaded before .Net tries to search the different places??

由于来自检查以前引用的程序集的事实,我认为可以预先将程序集加载到域中,然后执行此操作.

Due to the facts from Checking for Previously Referenced Assemblies i thought it would be possible to load the assembly beforehand into the domain and this would be taken.

我在 program.cs 中尝试使用以下 Main() 方法

I tried this within program.cs by using the following Main() method

static void Main()
{
    LoadMyAssemblies();
    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => LoadMyAssemblies();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

private static Assembly LoadMyAssemblies()
{
    Assembly result = AppDomain.CurrentDomain.Load(Properties.Resources.MyStaticAssembly);
    return result;
}

但它仍然运行到 ResolveEventHandler 中.更好的是,如果我再次加载程序集并查看 AppDomain.CurrentDomain.GetAssemblies(),我可以看到我的程序集加载了两次!!

But it still runs into the ResolveEventHandler. And far more better, if i load the assembly again and take a look into AppDomain.CurrentDomain.GetAssemblies() i can see that my assembly is loaded twice!!

所以知道为什么我加载的程序集在 AssemblyResolve 事件之前加载时不会被考虑在内吗?在调试器的帮助下,当调用来自 AssemblyResolve 时,我也返回了一个 null,但在这种情况下,我在开始时得到了 FileNotFoundException.

So any idea why my loaded assembly won't be taken into account when it is loaded before the AssemblyResolve event?? With help of the debugger i also returned a null when the call came from AssemblyResolve, but in this case i got a FileNotFoundException as at the beginning.

推荐答案

CLR Binder 不知道 LoadMyAssemblies() 与 AssemblyResolve 事件做同样的事情,而且它们都试图寻找相同的程序集和加载它.

The CLR Binder doesn't know that LoadMyAssemblies() does the same thing as the AssemblyResolve event, and that they are both trying to look for the same assembly and load it.

AssemblyResolve 事件总是在 Binder 决定它已经搜索了所有可能的位置(可以在该应用程序中搜索)并且找不到匹配项时触发.

AssemblyResolve event always gets fired at the point at which the Binder decides that it has searched all possible locations (that are searchable wrt that application) and could not find a match.

这引出了最初的问题,即,为什么要静态链接托管程序集?阅读此主题以了解有关此静态链接优势

This begs the original question, which is, why would you want to statically link your managed assemblies? Read this thread for a lot of discussion on this Static linking advantages

我将继续回答有关如何避免遇到 AssemblyResolve 事件的部分1) 将程序集放入 GAC.就 Binder 而言,GAC 总是获胜.2) 将您的程序集放在探测路径中,并确保 Binder 将其拾取(有关更多信息,请参阅 MSDN 上的文章运行时如何定位程序集").

I'll go ahead and answer the part on how to avoid hitting the AssemblyResolve event 1) Put the assembly into the GAC. As far as the Binder is concerned, the GAC always wins. 2) Place your assembly in the probing path and make sure that the Binder picks it up (look for the article 'How the runtime locates assemblies' on MSDN for more on this).

这篇关于如何在 AssemblyResolve 事件之前在运行时加载程序集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆