该 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”追加。
如果存在任何匹配的文件,则尝试加载并返回它。
非托管(本机)库探测
运行时的非托管库探测算法在所有平台上都是相同的。 但是,由于非托管库的实际负载由基础平台执行,因此观察到的行为可能略有不同。
检查提供的库名称是否表示绝对路径或相对路径。
如果名称表示绝对路径,请直接对所有后续作使用该名称。 否则,请使用该名称并创建要考虑的平台定义组合。 组合包括特定于平台的前缀(例如,
lib
)和/或后缀(例如,.dll
,和.dylib
.so
)。 这不是一个详尽的列表,它并不表示在每个平台上所做的确切工作。 这只是一个需考虑的示例。 有关详细信息,请参阅 本地库加载。如果路径是相对路径,则在以下步骤中使用该名称和每个组合。 第一次成功加载尝试会立即将句柄返回到加载的库。
将其追加到属性中
NATIVE_DLL_SEARCH_DIRECTORIES
提供的每个路径,并尝试加载。如果 DefaultDllImportSearchPathsAttribute 没有在调用程序集或 p/invoke 上被定义,或已经定义且包含
DllImportSearchPath.AssemblyDirectory
,请将其名称或组合追加到调用程序集的目录中,然后尝试加载。使用它直接加载库。
指示该库未能加载。