托管程序集与具有不同阶段的算法一起定位并加载。
除附属程序集和 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事件。