gpt4 book ai didi

c# - 为什么我需要一个已加载程序集的 AssemblyResolve 处理程序?

转载 作者:可可西里 更新时间:2023-11-01 09:08:58 25 4
gpt4 key购买 nike

我有两个程序集:AppAddOnApp 引用 AddOn,但 CopyLocal 设置为 false,因为 AddOn 将由 App 动态加载。

这是 AddOn 中的代码:

namespace AddOn
{
public class AddOnClass
{
public static void DoAddOnStuff()
{
Console.WriteLine("AddOn is doing stuff.");
}
}
}

这是App中的代码:

class Program
{
static void Main(string[] args)
{
Assembly.LoadFrom(@"..\..\..\AddOn\bin\Debug\AddOn.dll");

// Without this event handler, we get a FileNotFoundException.
// AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
// {
// return AppDomain.CurrentDomain.GetAssemblies()
// .FirstOrDefault(a => a.FullName == e.Name);
//};

CallAddOn();
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void CallAddOn()
{
AddOnClass.DoAddOnStuff();
}
}

我不明白的是为什么代码不能与 Main() 中注释的 AssemblyResolve 处理程序一起工作。在 Visual Studio 中运行时,调试器在 CallAddOn() 处中断并出现 FileNotFoundException。它为什么提示?程序集已加载,它与 App 引用的版本完全相同(即磁盘上的文件相同)。

我觉得这里有一些我没有正确理解的基本概念。评论的 AssemblyResolve 处理程序工作正常,但它似乎是一个 hack,我不明白为什么我需要它,因为它似乎在做一些微不足道的事情。

最佳答案

原因是存在多个程序集加载上下文。程序集加载到的上下文会影响它的使用方式。当运行时使用默认探测机制加载程序集时,它会被放入所谓的加载上下文中。这是通过 Assembly.Load 加载程序集时使用的上下文.您已使用 LoadFrom 加载程序集它使用自己的上下文。探测不会检查 LoadFrom 上下文并且文件不在探测路径中,因此您需要为运行时解析它。然而,这不是对称的。如果在加载上下文中加载程序集,LoadFrom将首先从那里加载它(假设身份相同。对于未签名的程序集,路径是身份的一部分。)。我会注意到还有更多上下文,包括 ReflectionOnlyLoadReflectionOnlyLoadFrom . LoadFile在没有上下文的情况下加载程序集,即必须手动加载所有依赖项。

如果您希望在加载上下文中解析程序集,但让它们存在于应用程序的默认探测路径之外,您也可以通过配置来实现。使用 <codebase> 程序集绑定(bind)重定向的元素或 privatePath <probing> 的属性元素。

阅读this想要查询更多的信息。 Suzanne Cook 不久前也发表了一些关于程序集加载和上下文的博客文章(请参阅 hereherehere)。

关于c# - 为什么我需要一个已加载程序集的 AssemblyResolve 处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20207643/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com