默认 AppDomain 与新 AppDomain 中不同的依赖解析行为加载程序集

Different dependency resolution behavior loading assembly in default AppDomain vs new AppDomain

我一直在研究与单元测试和 managed/native 通过 C++/CLI 互操作相关的问题。细节并不重要,所以除非被问到,否则我不会填写它们,但情况可以提炼如下:

两个程序集,称为 Lib 和 Dep,存在于同一目录中,称为 D。Lib 通过程序集引用依赖于 Dep。我们 运行ning 在一个位于不同的、不相关的目录中的应用程序中。应用程序创建一个新的 AppDomain,并将 ApplicationBase 设置为目录 D,加载 Lib 程序集,并尝试通过反射在其中构造一个类型。

作为 Lib 模块构造函数的一部分,我们转换到默认的 AppDomain 并加载引用的程序集 Dep。因为默认AppDomain的ApplicationBase不是目录D,无法解析Dep,抛出FileNotFoundException,加载Lib程序集失败。

这一切都是有道理的 -- 尽管可能很复杂,但我们试图加载一个不在当前 AppDomain 的程序集解析路径上的程序集,但失败了。

但是如果我 运行 这整个过程都在默认的 AppDomain 中而不是创建一个新的 AppDomain,则不会失败。即使目录 D 不是 ApplicationBase,也会加载 Lib 程序集,并且代码会正确实例化其 类 运行 之一。模块构造函数代码在默认的 AppDomain 中应该仍然是 运行,尽管它不需要转换到它。

在我看来,第二种情况应该像第一种情况一样失败。这两种情况的程序集引用解析过程有何不同?

好的,我通过比以前更完整地阅读 the MSDN page "How the Runtime Locates Assemblies" 找到了我之前遗漏的东西。最后一节 "Other Locations Probed" 概述了在为正在加载的程序集解析引用时,加载程序集的位置被视为可以找到引用程序集的位置的提示。

根据我看到的行为,我认为我们可以推断提示信息是特定于 AppDomain 的,这样就不会在触发原始程序集加载的 AppDomain 之外考虑提示。

我用我的测试项目验证了这一点——如果引用的程序集没有切换到默认的 AppDomain,那么它会正确加载。所以这不是默认的 AppDomain 特殊行为,它是一般的 AppDomain 约束行为。