![]() |
1
0
很好的回答来自 Vitek Karas ,原始链接 here 。 有点不幸的是,您描述的所有行为都是当前设计的。这并不意味着它是直观的(完全不是)。我来解释一下。 程序集绑定基于assemblyloadcontext(alc)进行。每个ALC只能加载任何给定程序集的一个版本(因此只有一个给定简单名称的程序集,忽略版本、区域性、键等)。您可以创建一个新的ALC,然后可以使用相同或不同的版本再次加载任何程序集。因此,ALC提供绑定隔离。 您的.exe和相关程序集将加载到运行时开始时创建的默认alc-one中。 assembly.loadfrom将尝试将指定的文件加载到默认的alc-always中。我来强调一下“试试”这个词。如果默认ALC已加载同名程序集,并且已加载的程序集的版本等于或更高,则LoadFrom将成功,但它将使用已加载的程序集(有效地忽略指定的路径)。另一方面,如果已经加载的程序集是较低版本,那么您尝试加载的程序集-这将失败(我们不能将同一程序集第二次加载到同一ALC中)。 assembly.load file将把指定的文件加载到一个新的ALC中-总是创建一个新的ALC。因此,负载将始终有效地成功(这是不可能与任何东西发生碰撞的,因为它是在自己的ALC中)。 所以现在来看看你的场景: 测试1 这是因为resolveassembly事件处理程序将两个程序集加载到单独的ALC中(loadfile将创建一个新程序集,因此第一个程序集将转到默认ALC,第二个程序集将转到它自己的ALC中)。 测试2 此操作失败,因为LoadFrom尝试将程序集加载到默认ALC中。当assemblyresolve处理程序调用第二个loadfrom时,该失败实际上发生在该处理程序中。第一次将v1加载到默认值时,第二次尝试将v2加载到默认值时失败,因为默认值已经加载了v1。 测试3 这同样失败了,因为它在内部基本上与test2完全相同。assembly.loadfrom还为assemblyresolve注册事件处理程序,确保可以从同一文件夹加载依赖程序集。因此,在您的情况下,v1\wrapper.v1.dll将把它的依赖关系解析为v1\thirdpartydependency.dll,因为它在磁盘上紧挨着它。然后对于v2,它将尝试执行相同的操作,但是v1已经加载,所以它失败了,就像在test2中一样。记住,loadFrom将所有内容加载到默认ALC中,因此可能发生冲突。 您的问题: 问题1 loadfile工作是因为它将程序集加载到自己的ALC中,ALC提供了完全隔离,因此没有任何冲突。loadFrom将程序集加载到默认ALC中,因此如果已经加载了同名程序集,则可能存在冲突。 问题2 该版本实际上不被忽略。这个版本很荣幸,这就是为什么test2和test3失败的原因。但我可能无法正确理解这个问题——我不清楚你在哪种情况下问这个问题。 clr绑定顺序 您描述的规则顺序不同。 基本上是:
规则3实际上不存在。.NET核心没有探测路径或代码库的概念。对于应用程序静态引用的程序集,它有点类似,但对于动态加载的程序集,不执行探测(从与父程序相同的文件夹加载依赖程序集的loadfrom除外,如上所述)。 解决 要使其完全工作,您需要执行以下任一操作:
我们正在积极努力使这种情况变得容易。今天它们是可行的,但相当困难。计划是要有一些东西来解决.NET核心3的问题。我们也很清楚这方面缺乏文件/指导。最后但并非最不重要的是,我们正在努力改进错误消息,这目前非常令人困惑。 |
![]() |
A B · C#Excel自动调整列避免长文本时出错 7 月前 |
![]() |
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 7 月前 |
![]() |
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 7 月前 |
|
Sei · Avalonia/WPF将路由器传递到控制模板 8 月前 |