我正在使用第三方程序集,不幸的是它吞下了它的异常,所以我决定使用 Mono.Cecil 重写程序集(幸运的是它不是强类型)(在对 DI 和 AOP 进行一些研究后发现了这个宝石)。我试图找到尽可能多的信息,但我仍然对 IL 的组成有一些疑问。
我已经阅读了 this和this,所以我知道我需要做什么,但就像我说的那样,我不确定如何生成正确的 IL 来进行调用。
我已经使用 Cecil 从我正在执行简单的 try/catch 的方法中提取指令 -> 登录 Elmah -> 让异常继续,这是我需要注入的。
这是我试图复制的捕获:
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(System.Web.HttpContext.Current)
.Log(new Elmah.Error(ex));
throw;
}
这些是我使用 Cecil 获得的 catch 块指令:
IL_010d: stloc.s V_7
IL_010f: nop
IL_0110: call System.Web.HttpContext System.Web.HttpContext::get_Current()
IL_0115: call Elmah.ErrorLog Elmah.ErrorLog::GetDefault(System.Web.HttpContext)
IL_011a: ldloc.s V_7
IL_011c: newobj System.Void Elmah.Error::.ctor(System.Exception)
IL_0121: callvirt System.String Elmah.ErrorLog::Log(Elmah.Error)
IL_0126: pop
IL_0127: rethrow
IL_0129: nop
我正在尝试使用 Cecil 复制这个块,这就是我已经走了多远:
var currentHttpContextInstruction = ilProcessor.Create(OpCodes.Call, module.Import(typeof(System.Web.HttpContext).GetProperty("Current").GetGetMethod()));
var elmahGetDefaultInstruction = ilProcessor.Create(OpCodes.Call, module.Import(typeof(Elmah.ErrorLog).GetMethod("GetDefault")));
var instantiateElmahErrorInstruction = ilProcessor.Create(OpCodes.Newobj, module.Import(typeof(Elmah.Error).GetConstructor(new[] { typeof(System.Exception) })));
var elmahErrorLogInstruction = ilProcessor.Create(OpCodes.Callvirt, module.Import(typeof(Elmah.ErrorLog).GetMethod("Log")));
var rethrowInstruction = ilProcessor.Create(OpCodes.Rethrow);
我不太确定的是如何正确复制剩余的指令......
我是否只是创建一个new VariableDefinition
,将其添加到method.Body.Variables
然后对该变量执行stloc
and操作?和命令呢ldloc
?我需要担心这个问题中提出的问题吗?nop
pop
任何有关如何以正确方式执行此操作的指导将不胜感激!
请注意,我已经查看了命令的含义,所以我的问题不在于它们的含义。