private static MethodDefinition EditMethod(MethodDefinition method, List <CustomAttribute> atts) { if (null == method || null == atts || atts.Count == 0) { return(null); } atts = atts.Distinct().ToList(); ILProcessor il = method.Body.GetILProcessor(); MethodDefinition newmethod = method.Clone(); method.Body.Instructions.Clear(); atts.ForEach(a => method.CustomAttributes.Remove(a)); if (!method.IsConstructor) { method.Body.Variables.Clear(); method.Body.ExceptionHandlers.Clear(); } var methbase = new VariableDefinition(method.Module.ImportReference(typeof(ExceEventArg))); method.Body.Variables.Add(methbase); var exception = new VariableDefinition(method.Module.ImportReference(typeof(System.Exception))); method.Body.Variables.Add(exception); var ps = new VariableDefinition(method.Module.ImportReference(typeof(List <object>))); method.Body.Variables.Add(ps); VariableDefinition returnvalue = null; var returnvoid = method.ReturnType.FullName == "System.Void"; if (!returnvoid) { returnvalue = new VariableDefinition(method.Module.ImportReference(method.ReturnType)); method.Body.Variables.Add(returnvalue); } var curmethod = method.Module.ImportReference(typeof(MethodBase).GetMethod("GetCurrentMethod")); il.AppendArr(new[] { il.Create(OpCodes.Newobj, method.Module.ImportReference(typeof(ExceEventArg).GetConstructor(new Type[] { }))), il.Create(OpCodes.Stloc_S, methbase), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Call, curmethod), il.Create(OpCodes.Callvirt, method.Module.CreateMethod <ExceEventArg>("set_methodBase", typeof(MethodBase))), }); if (method.Parameters.Count > 0) { il.AppendArr(new[] { il.Create(OpCodes.Newobj, method.Module.ImportReference(typeof(List <object>).GetConstructor(new Type[] { }))), il.Create(OpCodes.Stloc_S, ps), }); foreach (var p in method.Parameters) { il.Append(il.Create(OpCodes.Ldloc_S, ps)); il.Append(il.Create(OpCodes.Ldarg_S, p)); il.Append(il.Create(OpCodes.Box, method.Module.ImportReference(p.ParameterType))); il.Append(il.Create(OpCodes.Call, method.Module.CreateMethod <List <object> >("Add", typeof(object)))); } il.AppendArr(new[] { il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Ldloc_S, ps), il.Create(OpCodes.Callvirt, method.Module.CreateMethod <ExceEventArg>("set_parameters", typeof(List <object>))), }); } List <TypeDefinition> typeDefinitions = new List <TypeDefinition>(); List <VariableDefinition> variables = new List <VariableDefinition>(); Dictionary <CustomAttribute, Dictionary <string, Instruction> > excehandler = new Dictionary <CustomAttribute, Dictionary <string, Instruction> >(); for (int i = 0; i < atts.Count(); i++) { var excedic = new Dictionary <string, Instruction> { { "TryStart", il.Create(OpCodes.Nop) }, { "TryEnd", il.Create(OpCodes.Stloc_S, exception) }, { "HandlerStart", il.Create(OpCodes.Nop) }, { "HandlerEnd", il.Create(OpCodes.Nop) } }; excehandler.Add(atts[i], excedic); var w = new ExceptionHandler(ExceptionHandlerType.Catch) { CatchType = method.Module.ImportReference(typeof(Exception)), TryStart = excehandler[atts[i]]["TryStart"], TryEnd = excehandler[atts[i]]["TryEnd"], HandlerStart = excehandler[atts[i]]["TryEnd"], HandlerEnd = excehandler[atts[i]]["HandlerEnd"] }; method.Body.ExceptionHandlers.Add(w); TypeDefinition re = atts[i].AttributeType.Resolve(); typeDefinitions.Add(re); var begin = SearchMethod(re, "Before"); var log = new VariableDefinition(method.Module.ImportReference(atts[i].AttributeType)); method.Body.Variables.Add(log); variables.Add(log); il.AppendArr(new[] { il.Create(OpCodes.Newobj, atts[i].Constructor), il.Create(OpCodes.Stloc_S, log), }); if (begin != null) { il.AppendArr(new[] { il.Create(OpCodes.Ldloc_S, log), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Call, begin), }); } } for (int i = atts.Count - 1; i >= 0; i--) { il.Append(excehandler[atts[i]]["TryStart"]); } if (method.IsConstructor) { newmethod.Body.Instructions.RemoveAt(newmethod.Body.Instructions.Count - 1); il.AppendArr(newmethod.Body.Instructions.ToArray()); } else { if (!method.IsStatic) { il.Append(il.Create(OpCodes.Ldarg_0)); } foreach (var p in method.Parameters) { il.Append(il.Create(OpCodes.Ldarg_S, p)); } il.Append(il.Create(OpCodes.Call, newmethod)); } if (!returnvoid) { il.AppendArr(new[] { il.Create(OpCodes.Stloc_S, returnvalue), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Ldloc_S, returnvalue), il.Create(OpCodes.Box, method.Module.ImportReference(method.ReturnType)), il.Create(OpCodes.Callvirt, method.Module.CreateMethod <ExceEventArg>("set_returnValue", method.ReturnType.GetType())), }); } for (int i = 0; i < atts.Count(); i++) { var exce = SearchMethod(typeDefinitions[i], "Exception"); il.AppendArr(new[] { il.Create(OpCodes.Leave_S, excehandler[atts[i]]["HandlerEnd"]), excehandler[atts[i]]["TryEnd"], il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Ldloc_S, exception), il.Create(OpCodes.Callvirt, method.Module.CreateMethod <ExceEventArg>("set_exception", typeof(Exception))), il.Create(OpCodes.Ldloc_S, variables[i]), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Call, exce), il.Create(OpCodes.Nop), il.Create(OpCodes.Leave_S, excehandler[atts[i]]["HandlerEnd"]), excehandler[atts[i]]["HandlerEnd"], }); var after = SearchMethod(typeDefinitions[i], "After"); if (after != null) { il.AppendArr(new[] { il.Create(OpCodes.Ldloc_S, variables[i]), il.Create(OpCodes.Ldloc_S, methbase), il.Create(OpCodes.Call, after), }); } } if (!returnvoid) { il.Append(il.Create(OpCodes.Ldloc_S, returnvalue)); } il.Append(il.Create(OpCodes.Ret)); if (method.IsConstructor) { return(null); } return(newmethod); }