protected virtual void DealMethodInject(CustomAttribute methodInject, TypeDefinition mtype, MethodDefinition method, InjectAttributeUsage usage, PropertyDefinition property) { var il = method.Body.GetILProcessor(); var module = method.Module; var newmethod = CompilerGeneratedNewMethod(method, module); if (!newmethod.CustomAttributes.Any(t => t.AttributeType.FullName == typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute).FullName)) { newmethod.CustomAttributes.Add(new CustomAttribute(module.Import(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute).GetConstructor(new Type[0])))); } mtype.Methods.Add(newmethod); method.Body.Instructions.Clear(); method.Body.ExceptionHandlers.Clear(); method.Body.Variables.Clear(); method.Body.Instructions.Add(il.Create(OpCodes.Nop)); method.Body.InitLocals = false; ILMethodBuilder methodBuilder = new ILMethodBuilder(method); methodBuilder.Method = method; methodBuilder.SetTryStart(); //var varexception = new VariableDefinition(module.Import(typeof(System.Exception))); //method.Body.Variables.Add(varexception); methodBuilder.AddExceptonVar(new VariableDefinition(module.Import(typeof(System.Exception)))); var imethodInject = new VariableDefinition(module.Import(typeof(IMethodInject))); methodBuilder.AddVar(imethodInject); var varmethodexcetionEventargs = new VariableDefinition(module.Import(typeof(MethodExecutionEventArgs))); methodBuilder.AddVar(varmethodexcetionEventargs); var varmethodbase = new VariableDefinition(module.Import(typeof(MethodBase))); methodBuilder.AddVar(varmethodbase); var varinstance = new VariableDefinition(module.Import(typeof(object))); methodBuilder.AddVar(varinstance); var varparams = new VariableDefinition(module.Import(typeof(object[]))); methodBuilder.AddVar(varparams); var varExceptionStrategy = new VariableDefinition(module.Import(typeof(ExceptionStrategy))); methodBuilder.AddVar(varExceptionStrategy); // MethodBase if (usage == InjectAttributeUsage.Property) { methodBuilder.AddRange(new[] { il.Create(OpCodes.Ldtoken, mtype), il.Create(OpCodes.Call, module.Import(typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) }))), il.Create(OpCodes.Ldstr, property.Name), il.Create(OpCodes.Ldtoken, method.IsGetter?method.ReturnType:method.Parameters[0].ParameterType), il.Create(OpCodes.Call, module.Import(typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) }))), il.Create(OpCodes.Call, module.Import(typeof(System.Type).GetMethod("GetProperty", new Type[] { typeof(string), typeof(Type) }))), il.Create(OpCodes.Stloc_S, varmethodbase), }); } else { methodBuilder.AddRange(new[] { il.Create(OpCodes.Nop), il.Create(OpCodes.Call, module.Import(typeof(MethodBase).GetMethod("GetCurrentMethod"))), il.Create(OpCodes.Stloc_S, varmethodbase), }); } // 函数参数 methodBuilder.AddRange(new[] { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, varmethodbase), il.Create(OpCodes.Ldtoken, module.Import(typeof(IMethodInject))), il.Create(OpCodes.Call, module.Import(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }))), il.Create(OpCodes.Ldc_I4_0), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodBase).GetMethod("GetCustomAttributes", new[] { typeof(Type), typeof(bool) }))), il.Create(OpCodes.Stloc_S, varparams), il.Create(OpCodes.Ldloc_S, varparams), il.Create(OpCodes.Ldlen) }) .Ifelsetrue(() => new List <Instruction> { il.Create(OpCodes.Ldloc_S, varparams), il.Create(OpCodes.Ldc_I4_0), il.Create(OpCodes.Ldelem_Ref), il.Create(OpCodes.Isinst, module.Import(typeof(IMethodInject))), il.Create(OpCodes.Stloc_S, imethodInject), }, () => new List <Instruction> { il.Create(OpCodes.Ldnull), il.Create(OpCodes.Stloc_S, imethodInject), }) .AddRange(new[] { il.Create(OpCodes.Ldnull), il.Create(OpCodes.Stloc_S, varinstance), il.Create(OpCodes.Ldloc_S, varmethodbase), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodBase).GetMethod("get_IsStatic"))), il.Create(OpCodes.Ldc_I4_0), il.Create(OpCodes.Ceq) }) .Iffalse(() => new List <Instruction> { il.Create(OpCodes.Nop), }, () => new List <Instruction> { il.Create(OpCodes.Ldarg_0) }); methodBuilder.AddRange(new[] { il.Create(OpCodes.Ldloc_S, varmethodbase), il.Create(OpCodes.Ldloc_S, varinstance), il.Create(OpCodes.Ldloc_S, varparams), }); if (method.ReturnType.FullName != "System.Void") { methodBuilder.Add(il.Create(OpCodes.Ldstr, method.ReturnType.FullName)); } else { methodBuilder.Add(il.Create(OpCodes.Ldnull)); } methodBuilder.AddRange(new[] { il.Create(OpCodes.Newobj, module.Import(typeof(MethodExecutionEventArgs).GetConstructor(new [] { typeof(MethodBase), typeof(object), typeof(object[]), typeof(string) }))), il.Create(OpCodes.Stloc_S, varmethodexcetionEventargs) }); // 初始化ImethodInject //methodBuilder.AddRange(new[] //{ // il.Create(OpCodes.Nop), // il.Create(OpCodes.Ldtoken,methodInject.AttributeType ), // il.Create(OpCodes.Call,module.Import(typeof(System.Type).GetMethod("GetTypeFromHandle",new Type[]{typeof(System.RuntimeTypeHandle)}))), // il.Create(OpCodes.Ldc_I4_0), // il.Create(OpCodes.Callvirt,module.Import(typeof(System.Reflection.MemberInfo).GetMethod("GetCustomAttributes",new Type[]{typeof(System.Type),typeof(bool)}))), // il.Create(OpCodes.Ldc_I4_0), // il.Create(OpCodes.Ldelem_Ref), // il.Create(OpCodes.Isinst,methodInject.AttributeType), // il.Create(OpCodes.Stloc_S,imethodInject) //}); //执行开始函数 methodBuilder.AddRange(new[] { il.Create(OpCodes.Ldloc_S, imethodInject), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(IMethodInject).GetMethod("Executeing", new Type[] { typeof(MethodExecutionEventArgs) }))), il.Create(OpCodes.Pop) }); // 调用原来的函数 // 判断是不是静态函数 if (!method.IsStatic) { methodBuilder.Add(il.Create(OpCodes.Ldarg_0)); } method.Parameters.ToList().ForEach(t => { methodBuilder.Add(il.Create(OpCodes.Ldarg_S, t)); }); methodBuilder.AddRange(new[] { il.Create(OpCodes.Call, newmethod), }); if (method.ReturnType.FullName != "System.Void") { var varreturnValue = new VariableDefinition(method.ReturnType); method.MethodAddVar(varreturnValue); methodBuilder.Lastreturn = il.Create(OpCodes.Ldloc_S, varreturnValue); methodBuilder.AddRange(new[] { il.Create(OpCodes.Stloc_S, varreturnValue), }); // 执行完成函数 methodBuilder.AddRange(new[] { il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Ldloc_S, varreturnValue), il.Create(OpCodes.Box, module.Import(method.ReturnType)), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodExecutionEventArgs).GetMethod("set_ReturnValue", new [] { typeof(object) }))), il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, imethodInject), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(IMethodInject).GetMethod("Executed", new Type[] { typeof(MethodExecutionEventArgs) }))), il.Create(OpCodes.Nop), }); methodBuilder.AddRange(new[] { il.Create(OpCodes.Leave_S, methodBuilder.Lastreturn), il.Create(OpCodes.Nop) }); methodBuilder.SetTryEnd() .SetHandleStart() .AddRange(new[] { il.Create(OpCodes.Stloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), //il.Create(OpCodes.Box,module.Import(methodBuilder.ExceptionVar.GetType())), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodExecutionEventArgs).GetMethod("set_Exception", new [] { typeof(Exception) }))), il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, imethodInject), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(IMethodInject).GetMethod("Exceptioned", new Type[] { typeof(MethodExecutionEventArgs) }))), il.Create(OpCodes.Stloc_S, varExceptionStrategy), //il.Create(OpCodes.Ldloc_S,methodBuilder.ExceptionVar), il.Create(OpCodes.Ldloc_S, varExceptionStrategy), }); //switch methodBuilder.Switch(() => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodExecutionEventArgs).GetMethod("get_ReturnValue", new Type[] {}))), il.Create(OpCodes.Unbox_Any, method.ReturnType), il.Create(OpCodes.Stloc_S, varreturnValue), il.Create(OpCodes.Leave_S, methodBuilder.Lastreturn) }, // handle () => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodExecutionEventArgs).GetMethod("get_ReturnValue", new Type[] {}))), il.Create(OpCodes.Unbox_Any, method.ReturnType), il.Create(OpCodes.Stloc_S, varreturnValue), il.Create(OpCodes.Leave_S, methodBuilder.Lastreturn) }, // throw () => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Throw) }, () => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Throw) }); methodBuilder.SetHandleEnd() .AddRange(new[] { methodBuilder.Lastreturn, il.Create(OpCodes.Ret) }); } else { // 执行完成函数 methodBuilder.AddRange(new[] { il.Create(OpCodes.Ldloc_S, imethodInject), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(IMethodInject).GetMethod("Executed", new Type[] { typeof(MethodExecutionEventArgs) }))), il.Create(OpCodes.Stloc_S, varExceptionStrategy), il.Create(OpCodes.Nop) }); methodBuilder.AddRange(new[] { il.Create(OpCodes.Leave_S, methodBuilder.Lastreturn), il.Create(OpCodes.Nop) }) .SetTryEnd() .SetHandleStart() .AddRange(new[] { il.Create(OpCodes.Stloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), //il.Create(OpCodes.Box,methodBuilder.ExceptionVar), il.Create(OpCodes.Callvirt, module.Import(typeof(MethodExecutionEventArgs).GetMethod("set_Exception", new [] { typeof(Exception) }))), il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, imethodInject), il.Create(OpCodes.Ldloc_S, varmethodexcetionEventargs), il.Create(OpCodes.Callvirt, module.Import(typeof(IMethodInject).GetMethod("Exceptioned", new Type[] { typeof(MethodExecutionEventArgs) }))), il.Create(OpCodes.Stloc_S, varExceptionStrategy), il.Create(OpCodes.Ldloc_S, varExceptionStrategy), //il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), //il.Create(OpCodes.Callvirt,method.Module.Import(typeof(System.Object).GetMethod("ToString"))), //il.Create(OpCodes.Call,method.Module.Import(typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }))), //il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), //il.Create(OpCodes.Throw), }); // switch methodBuilder.Switch(() => new List <Instruction> { il.Create(OpCodes.Nop), }, // handle () => new List <Instruction> { il.Create(OpCodes.Nop), }, // throw () => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Throw) }, () => new List <Instruction> { il.Create(OpCodes.Nop), il.Create(OpCodes.Ldloc_S, methodBuilder.ExceptionVar), il.Create(OpCodes.Throw) }); methodBuilder.AddRange(new[] { il.Create(OpCodes.Leave_S, methodBuilder.Lastreturn), il.Create(OpCodes.Nop) }); methodBuilder.SetHandleEnd() .Add(methodBuilder.Lastreturn); } methodBuilder.Build(); //var business = il.Create(OpCodes.Call, newmethod); //var exception = il.Create(OpCodes.Stloc_S, varexception); //var tryEnd = il.Create(OpCodes.Nop); //var handerEnd = il.Create(OpCodes.Nop); //var rethrow = il.Create(OpCodes.Throw); //ILProcessorExsions.InsertAfter(il, method.Body.Instructions.Last(), new[] { business }); //if (method.ReturnType.FullName != "System.Void") //{ // var varreturnValue = new VariableDefinition(method.ReturnType); // method.Body.Variables.Add(varreturnValue); // var lastreturn = il.Create(OpCodes.Ldloc_S, varreturnValue); // ILProcessorExsions.Append(il, new[] // { // //il.Create(OpCodes.Unbox_Any, method.ReturnType), // il.Create(OpCodes.Stloc_S, varreturnValue), // //il.Create(OpCodes.Br_S, lastreturn), // il.Create(OpCodes.Leave_S,lastreturn) , // tryEnd, // exception, // il.Create(OpCodes.Ldloc_0), // rethrow, // handerEnd, // lastreturn // }); //} //else //{ // ILProcessorExsions.InsertAfter(il, method.Body.Instructions.Last(), new[] // { // tryEnd, // exception, // il.Create(OpCodes.Ldloc_0), // rethrow, // handerEnd, // }); //} ////method.Body.Instructions.Add(ret); //// try-catch //ILProcessorExsions.InsertAfter(il, method.Body.Instructions.Last(), new[] { ret }); //var handler = new ExceptionHandler(ExceptionHandlerType.Catch) //{ // TryStart = method.Body.Instructions.First(), // TryEnd = tryEnd, // HandlerStart = tryEnd, // HandlerEnd = handerEnd, // CatchType = module.Import(typeof(Exception)) //}; //method.Body.ExceptionHandlers.Add(handler); }
protected virtual void DealMethodInject(CustomAttribute methodInject, TypeDefinition mtype, MethodDefinition method, InjectAttributeUsage usage) { DealMethodInject(methodInject, mtype, method, usage, null); }