默认 AppDomain 与新 AppDomain 中不同的依赖解析行为加载程序集 [英] Different dependency resolution behavior loading assembly in default AppDomain vs new AppDomain

查看:24
本文介绍了默认 AppDomain 与新 AppDomain 中不同的依赖解析行为加载程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在通过 C++/CLI 查看与单元测试和托管/本机互操作相关的问题.细节不重要所以除非被问到我不会填写它们,但情况可以提炼如下:

I've been looking at an issue related to unit testing and managed/native interop via C++/CLI. The details aren't important so I won't fill them in unless asked, but the situation can be distilled as follows:

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

Two assemblies, call them Lib and Dep, exist in the same directory, call it D. Lib depends on Dep via an assembly reference. We are running in an application that lives in a different, unrelated directory. The application creates a new AppDomain with ApplicationBase set to directory D, loads the Lib assembly, and tries to construct a type in it via reflection.

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

As part of Lib's module constructor we transition into the default AppDomain and load the referenced assembly Dep. Because the default AppDomain's ApplicationBase is NOT directory D, Dep cannot be resolved, a FileNotFoundException is thrown, and loading the Lib assembly fails.

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

This all makes sense -- convoluted as it may be, we tried to load an assembly that's not on the assembly resolution path for the current AppDomain, and failed.

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

BUT if I run this whole process in the default AppDomain instead of creating a new AppDomain, there is no failure. Even through directory D is not the ApplicationBase, the Lib assembly is loaded and the code instantiating one of its classes runs correctly. The module constructor code should still be run in the default AppDomain although it does not need to transition to it.

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

It seems to me that the second case should fail just like the first one. What's different about the assembly reference resolution process between these two cases?

推荐答案

好的,我通过更完整的阅读 MSDN 页面运行时如何定位程序集" 比我以前所做的要多.最后一部分探查的其他位置"概述了在解析正在加载的程序集的引用时,加载的程序集的位置被视为可以找到被引用程序集的位置的提示.

OK, I found what I was missing before via a more complete reading of the MSDN page "How the Runtime Locates Assemblies" than I'd done before. The very last section, "Other Locations Probed" outlines that when resolving references for an assembly being loaded, the loaded assembly's location is taken as a hint for where the referenced assembly can be found.

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

Based on the behavior I'm seeing I think we can extrapolate that the hint information is AppDomain-specific, such that the hint is not taken into account outside the AppDomain that triggered the original assembly load.

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

I verified this with my test project -- if the referenced assembly does not switch into the default AppDomain then it loads correctly. So this is not default AppDomain special behavior, it's general AppDomain constrained behavior.

这篇关于默认 AppDomain 与新 AppDomain 中不同的依赖解析行为加载程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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