问题描述
假设我有一个 AppDomain.AssemblyResolve
事件,并在处理程序中构造一个字节数组并调用方法 Assembly.Load(字节[])
.此方法本身是否会导致 AssemblyResolve
事件再次引发,并导致我的处理程序重新进入?
Suppose I have a handler for AppDomain.AssemblyResolve
event, and in the handler I construct a byte array and invoke the method Assembly.Load(byte[])
. Can this method itself cause the AssemblyResolve
event to be raised again, and cause my handler to be re-entered?
我的问题不仅限于可以使用 C# 编译器生成的程序集,它们还可以包含 CLR 支持的 abritrary 元数据和可执行代码.
My question is not restricted only to assemblies that can be generated using C# compiler, they can contain abritrary metadata and executable code supported by the CLR.
我做了一些实验,没有发现任何发生的情况.我尝试加载需要额外引用的程序集,尝试将 CAS 属性添加到加载的程序集,其解码需要另一个程序集,尝试使用模块初始值设定项(全局 .cctor
方法)加载程序集.在任何情况下,我都没有观察到从 Assembly.Load(byte[])
方法内部引发的 AssemblyResolve
事件,只有在某些代码稍后尝试访问类型时才会发生,加载的程序集中的方法或属性.但我可能在这里遗漏了一些东西.
I did some experiments and haven't find any cases when it happens. I tried to load assemblies that require additional references, tried to add CAS attributes to the loaded assembly whose decoding would require another assembly, tried to load an assembly with a module initializer (global .cctor
method). In no case I observed the AssemblyResolve
event to be raised from inside the Assembly.Load(byte[])
method, it only happened if some code later tried to access types, methods or attributes in the loaded assembly. But I can be missing something here.
推荐答案
据我所知 Assembly.Load
或通过其他方式加载程序集不会执行任何可由 C# 编译器生成的构造函数(包括静态构造函数).因此,您不会在常见的程序集上重新进入 AssemblyResolve
.
To my knowledge Assembly.Load
or loading assembly by other means does not execute any constructors that can be generated by the C# compiler (including static constructors). As result you're not going to get reentrancy to AssemblyResolve
on commonly found assemblies.
正如您在问题中提到的,在 Load
调用期间不会执行模块初始值设定项.包含在 CLI 规范中的保证列表中 - 摘录可以在 Module Initializers 作者:Junfeng Zhang.
As you've mentioned in the question, module initializers are not executed during the Load
call. Covered in list of guarantees in CLI spec - excerpt can be found in Module Initializers by Junfeng Zhang.
B.模块的初始化方法在第一次访问模块中定义的任何类型、方法或数据时或之前的某个时间执行
有相关的 SO 问题通常讨论在任何类型构造函数之前运行代码",例如 初始化库装配负荷.请注意,.Net:加载程序集时运行代码 Marc Gravell 的回答指出,由于安全限制,这可能是不可能的.
There are related SO questions usually discussing "run code before any type constructors" like Initialize library on Assembly load. Note that .Net: Running code when assembly is loaded has an answer by Marc Gravell that states it may not be possible due to security constraints.
这篇关于调用 Assembly.Load(byte[]) 可以引发 AppDomain.AssemblyResolve 事件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!