默认探测

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

主机配置的探测属性

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

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

属性名称 DESCRIPTION
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默认情况下不会填充该属性,并且大多数应用程序都省略该属性。

可以通过访问应用程序使用的所有 System.AppContext.GetData("APP_CONTEXT_DEPS_FILES") 文件的列表。

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

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

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

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

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

托管程序集默认探测

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

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

附属(资源)程序集探测

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

对于PLATFORM_RESOURCE_ROOTS中的每个路径,然后在APP_PATHS中,将CultureInfo.Name字符串、目录分隔符、AssemblyName.Name字符串和文件扩展名“.dll”追加。

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

非托管(本机)库探测

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

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

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

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

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

    • 如果 DefaultDllImportSearchPathsAttribute 没有在调用程序集或 p/invoke 上被定义,或已经定义且包含 DllImportSearchPath.AssemblyDirectory,请将其名称或组合追加到调用程序集的目录中,然后尝试加载。

    • 使用它直接加载库。

  4. 指示该库未能加载。