默认探测

AssemblyLoadContext.Default 实例负责定位程序集的依赖项。 本文介绍 AssemblyLoadContext.Default 实例的探测逻辑。

主机配置的探测属性

运行时启动时,运行时主机提供一组命名的探测属性,这些属性可配置 AssemblyLoadContext.Default 探测路径。

每个探测属性均可选。 如果存在,则每个属性都是一个字符串值,其中包含绝对路径的分隔列表。 在 Windows 上,分隔符为“;”,在所有其他平台上,分隔符为“:”。

属性名 描述
TRUSTED_PLATFORM_ASSEMBLIES 平台和应用程序程序集文件路径的列表。
PLATFORM_RESOURCE_ROOTS 用于搜索附属资源程序集的目录路径的列表。
NATIVE_DLL_SEARCH_DIRECTORIES 用于搜索非托管(本机)库的目录路径的列表。
APP_PATHS 用于搜索托管程序集的目录路径的列表。

如何填充属性?

填充属性有两个主要方案,具体取决于 myapp>.deps.json 文件是否存在。

  • 当 *.deps.json 文件存在时,将对其进行分析以填充探测属性。
  • 如果 *.deps.json 文件不存在,则假定应用程序的目录以包含所有依赖项。 目录的内容用于填充探测属性。

此外,也会对任何引用框架的 *.deps.json 文件进行类似的分析。

可使用环境变量 DOTNET_ADDITIONAL_DEPS 添加其他依赖项。 dotnet.exe 还包含一个 --additional-deps 可选参数,用于在应用程序启动时设置此值。

默认不会填充 APP_PATHS 属性,大多数应用程序都省略了该属性。

可以通过 访问应用程序使用的所有 *.deps.jsonn 文件的列表。

如何查看托管代码中的探测属性?

通过使用上表中的属性名称调用 AppContext.GetData(String) 函数,可查看每个属性。

如何调试探测属性的构造?

启用某些环境变量后,.NET Core 运行时主机将输出有用的跟踪消息:

环境变量 描述
COREHOST_TRACE=1 启用跟踪。
COREHOST_TRACEFILE=<path> 跟踪文件路径而不是默认 stderr
COREHOST_TRACE_VERBOSITY 将详细程度设置为从 1(最低)到 4(最高)。

托管程序集默认探测

当探测以定位托管程序集时,AssemblyLoadContext.Default 会按以下顺序查找:

  • TRUSTED_PLATFORM_ASSEMBLIES 中的 AssemblyName.Name 匹配的文件(在删除文件扩展名之后)。
  • 包含公共文件扩展名的 APP_PATHS 中的程序集文件。

附属(资源)程序集探测

若要查找特定区域性的附属程序集,请构造一组文件路径。

对于 PLATFORM_RESOURCE_ROOTSAPP_PATHS 中的每个路径,附加 CultureInfo.Name 字符串、目录分隔符、AssemblyName.Name 字符串和扩展名“.dll”。

如果存在任何匹配的文件,请尝试加载并返回该文件。

非托管(本机)库探测

运行时的非托管库探测算法在所有平台上都是相同的。 但是,由于非托管库的实际加载由基础平台执行,因此观察到的行为可能略有不同。

  1. 检查提供的库名称是表示绝对路径还是相对路径。

  2. 如果该名称表示绝对路径,请直接将名称用于所有后续操作。 否则,请使用该名称并创建要考虑的平台定义组合。 组合由特定于平台的前缀(如 lib)和/或后缀(如 .dll.dylib.so)组成。 这不是一个详尽列表,并不代表在每个平台上进行的确切工作。 这只是一个需考虑的示例。 有关详细信息,请参阅本机库加载

  3. 如果路径是相对路径,则在以下步骤中使用该名称和每个组合。 第一次成功加载尝试会立即将句柄返回到加载的库。

    • 将它追加到 NATIVE_DLL_SEARCH_DIRECTORIES 属性中提供的每个路径,并尝试加载。

    • 如果 DefaultDllImportSearchPathsAttribute 未在调用程序集或 p/invoke 上定义或定义并包括 DllImportSearchPath.AssemblyDirectory,请将名称或组合追加到调用程序集的目录并尝试加载。

    • 直接使用它来加载库。

  4. 指示该库未能加载。