托管程序集加载算法
托管程序集与具有不同阶段的算法一起定位并加载。
除附属程序集和 WinRT
程序集之外的所有托管程序集都使用相同算法。
何时加载托管程序集?
触发托管程序集加载的最常见机制是静态程序集引用。 每当代码使用在另一个程序集中定义的类型时,编译器都会插入这些引用。 根据运行时的需要加载这些程序集 (load-by-name
)。 未指定加载静态程序集引用的确切时间。 它可能因运行时版本而异,并且受内联等优化影响。
直接使用以下 API 也将触发加载:
算法
以下算法描述运行时如何加载托管程序集。
确定
active
AssemblyLoadContext。- 对于静态程序集引用,
active
AssemblyLoadContext 是已加载引用程序集的实例。 - 首选 API 使
active
AssemblyLoadContext 显式。 - 其他 API 推断
active
AssemblyLoadContext。 对于这些 API,将使用 AssemblyLoadContext.CurrentContextualReflectionContext 属性。 如果其值为null
,则使用推断的 AssemblyLoadContext 实例。 - 请参阅何时加载托管程序集?部分中的表。
- 对于静态程序集引用,
对于
Load-by-name
方法,active
AssemblyLoadContext 按以下优先级顺序加载程序集:- 检查其
cache-by-name
。 - 调用 AssemblyLoadContext.Load 函数。
- 检查 AssemblyLoadContext.Default 实例的缓存并运行托管程序集默认探测逻辑。 如果程序集是新加载的,则会向 AssemblyLoadContext.Default 实例的
cache-by-name
添加一个引用。 - 引发活动 AssemblyLoadContext 的 AssemblyLoadContext.Resolving 事件。
- 引发 AppDomain.AssemblyResolve 事件。
- 检查其
对于其他加载类型,
active
AssemblyLoadContext 按以下优先级顺序加载程序集:- 检查其
cache-by-name
。 - 从指定的路径或原始程序集对象加载。 如果程序集是新加载的,则会向
active
AssemblyLoadContext 实例的cache-by-name
添加一个引用。
- 检查其
在任一情况下,如果新加载了一个程序集,则引发 AppDomain.AssemblyLoad 事件。