private static ILGenerator MakeGenericMethod(ILGenerator ilGenerator, MethodInfo method, LocalBuilder interceptedMethodLocal) { if (method.IsGenericMethod) { var genericArguments = method.GetGenericArguments(); var genericArgumentsLocal = ilGenerator.DeclareLocal(typeof(Type[])); var makeGenericMethod = typeof(MethodInfo).GetMethod("MakeGenericMethod"); ilGenerator.NewArray(typeof(Type), genericArguments.Length).StoreLocal(genericArgumentsLocal). ForEach(genericArguments, (_, arg, i) => ilGenerator.LoadLocal(genericArgumentsLocal).LoadInt(i).Typeof(arg).SetArrayItemRef()). LoadLocal(interceptedMethodLocal).LoadLocal(genericArgumentsLocal). Callvirt(makeGenericMethod).StoreLocal(interceptedMethodLocal); } return ilGenerator; }
private static void ExcepionIntercept(ILGenerator ilGenerator, IInterceptor[] interceptors, LocalBuilder[] local) { var excepionInterceptors = interceptors.GetExcepionInterceptors(); if (!excepionInterceptors.Any()) { ilGenerator.Emit(OpCodes.Throw); return; } var invocationType = InternalDynamicTypeProvider.CreateType<IExceptionInvocation>(); var setException = invocationType.GetMethod("set_Exception"); var setInterceptedType = invocationType.GetMethod("set_InterceptedType"); var setInterceptedInstance = invocationType.GetMethod("set_InterceptedInstance"); var getExceptionHandled = invocationType.GetMethod("get_ExceptionHandled"); var getExcepionInterceptMethod = typeof(IExceptionInterceptor).GetMethod("OnExcepion"); var getExcepionInterceptorsMethod = typeof(InterceptorExtends).GetMethod("GetExcepionInterceptors"); var exceptionLocal = ilGenerator.DeclareLocal(typeof(Exception)); var interceptorLocal = ilGenerator.DeclareLocal(typeof(IExceptionInterceptor[])); var invocationLocal = ilGenerator.DeclareLocal(invocationType); var breakExceptionLable = ilGenerator.DefineLabel(); ilGenerator.StoreLocal(exceptionLocal).LoadLocal(local[0]).Call(getExcepionInterceptorsMethod).StoreLocal(interceptorLocal); ilGenerator.New(invocationType.GetConstructor(Type.EmptyTypes)).StoreLocal(invocationLocal); ilGenerator.LoadLocal(invocationLocal).LoadLocal(exceptionLocal).Callvirt(setException); ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[2]).Callvirt(setInterceptedType); ilGenerator.LoadLocal(invocationLocal).This().Callvirt(setInterceptedInstance); ilGenerator.ForEach(excepionInterceptors, (il, interceptor, index) => il.LoadLocal(invocationLocal).Callvirt(getExceptionHandled).False(breakExceptionLable).LoadLocal(interceptorLocal).LoadArrayItem(index). LoadLocal(invocationLocal).Callvirt(getExcepionInterceptMethod)).MarkLabelFor(breakExceptionLable); }
private static void MethodIntercept(ILGenerator ilGenerator, MethodInfo methodInfo, IInterceptor[] interceptors, LocalBuilder[] local, bool[] boolean, Action<ILGenerator> method) { var methodInterceptors = interceptors.GetMethodInterceptor(); if (!methodInterceptors.Any()) { method(ilGenerator); return; } var invocationType = InternalDynamicTypeProvider.CreateType<IMethodInvocation>(); var returnParameterType = InternalDynamicTypeProvider.CreateType<IReturnParameter>(); var parameterType = InternalDynamicTypeProvider.CreateType<IParameter>(); var setParameters = invocationType.GetMethod("set_Parameters"); var setParameterValue = parameterType.GetMethod("set_Value"); var getParameterValue = parameterType.GetMethod("get_Value"); var setParameterName = parameterType.GetMethod("set_Name"); var setParameterInfo = parameterType.GetMethod("set_ParameterInfo"); var getParameterName = typeof(ParameterInfo).GetMethod("get_Name"); var getCurrentParameter = typeof(InterceptorExtends).GetMethod("GetCurrentParameter"); var setReturnParameter = invocationType.GetMethod("set_ReturnParameter"); var getReturnValue = returnParameterType.GetMethod("get_Value"); var setReturnType = returnParameterType.GetMethod("set_ReturnType"); var setReturnValue = returnParameterType.GetMethod("set_Value"); var returnParameterLocal = ilGenerator.DeclareLocal(returnParameterType); var getReturnType = typeof(MethodInfo).GetMethod("get_ReturnType"); var setInterceptedMethod = invocationType.GetMethod("set_InterceptedMethod"); var setInterceptedType = invocationType.GetMethod("set_InterceptedType"); var setInterceptedInstance = invocationType.GetMethod("set_InterceptedInstance"); var getExecutedHandled = invocationType.GetMethod("get_ExecutedHandled"); var getGetMethodInterceptor = typeof(InterceptorExtends).GetMethod("GetMethodInterceptor"); var getGetExecutedMethodInterceptor = typeof(InterceptorExtends).GetMethod("GetExecutedMethodInterceptor"); var onMethodExecuting = typeof(IMethodInterceptor).GetMethod("OnMethodExecuting"); var onMethodExecuted = typeof(IMethodInterceptor).GetMethod("OnMethodExecuted"); var interceptorLocal = ilGenerator.DeclareLocal(typeof(IMethodInterceptor[])); var executedInterceptorLocal = ilGenerator.DeclareLocal(typeof(IMethodInterceptor[])); var parametersLocal = ilGenerator.DeclareLocal(typeof(IParameter[])); var invocationLocal = ilGenerator.DeclareLocal(invocationType); var endLable = ilGenerator.DefineLabel(); ilGenerator.LoadLocal(local[0]).Call(getGetMethodInterceptor).StoreLocal(interceptorLocal); ilGenerator.LoadLocal(local[0]).Call(getGetExecutedMethodInterceptor).StoreLocal(executedInterceptorLocal); ilGenerator.New(invocationType.GetConstructor(Type.EmptyTypes)).StoreLocal(invocationLocal); ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[1]).Callvirt(setInterceptedMethod); ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[2]).Callvirt(setInterceptedType); ilGenerator.LoadLocal(invocationLocal).This().Callvirt(setInterceptedInstance); ilGenerator.New(returnParameterType.GetConstructor(Type.EmptyTypes)).StoreLocal(returnParameterLocal); if (boolean[0]) ilGenerator.LoadLocal(returnParameterLocal).LoadLocal(local[1]).Callvirt(getReturnType).Callvirt(setReturnType); else ilGenerator.LoadLocal(returnParameterLocal).Typeof(typeof(void)).Callvirt(setReturnType); ilGenerator.LoadLocal(invocationLocal).LoadLocal(returnParameterLocal).Callvirt(setReturnParameter); ilGenerator.NewArray(typeof(IParameter), methodInfo.GetParameters().Length).StoreLocal(parametersLocal); ilGenerator.ForEach(methodInfo.GetParameterTypes(), (il, arg, i) => { var argLocal = ilGenerator.DeclareLocal(parameterType); ilGenerator.New(parameterType.GetConstructor(Type.EmptyTypes)).StoreLocal(argLocal); ilGenerator.LoadLocal(argLocal).LoadArgument(i + 1).Box(arg).Callvirt(setParameterValue); ilGenerator.LoadLocal(argLocal).LoadLocal(local[1]).LoadInt(i).Call(getCurrentParameter).Callvirt(setParameterInfo); ilGenerator.LoadLocal(argLocal).LoadLocal(local[1]).LoadInt(i).Call(getCurrentParameter).Callvirt(getParameterName).Callvirt(setParameterName); ilGenerator.LoadLocal(parametersLocal).LoadInt(i).LoadLocal(argLocal).SetArrayItemRef(); }); ilGenerator.LoadLocal(invocationLocal).LoadLocal(parametersLocal).Callvirt(setParameters); ilGenerator.ForEach(methodInterceptors, (_, interceptor, index) => _.LoadLocal(interceptorLocal).LoadArrayItem(index).LoadLocal(invocationLocal) .Callvirt(onMethodExecuting).LoadLocal(invocationLocal).Callvirt(getExecutedHandled).False(endLable)); ilGenerator.ForEach(methodInfo.GetParameterTypes(), (il, arg, i) => { ilGenerator.LoadLocal(parametersLocal).LoadArrayItem(i).Callvirt(getParameterValue).UnBox(arg).StroeArgument(i + 1); }); method(ilGenerator); if (boolean[0]) ilGenerator.LoadLocal(returnParameterLocal).LoadLocal(local[3]).Callvirt(setReturnValue); ilGenerator.ForEach(methodInterceptors.OrderBy(i => i.ExecutedOrder), (_, interceptor, index) => _.LoadLocal(executedInterceptorLocal).LoadArrayItem(index).LoadLocal(invocationLocal). Callvirt(onMethodExecuted).LoadLocal(invocationLocal).Callvirt(getExecutedHandled).False(endLable)); ilGenerator.MarkLabelFor(endLable); if (boolean[0]) ilGenerator.LoadLocal(returnParameterLocal).Callvirt(getReturnValue).StoreLocal(local[3]); }
private static void ParameterIntercept(ILGenerator ilGenerator, IInterceptor[] interceptors, LocalBuilder[] local, MethodInfo method) { var parameterInterceptors = interceptors.GetParameterInterceptors(); if (!parameterInterceptors.Any()) return; var invocationType = InternalDynamicTypeProvider.CreateType<IParameterInvocation>(); var parameterType = InternalDynamicTypeProvider.CreateType<IParameter>(); var setInterceptedMethod = invocationType.GetMethod("set_InterceptedMethod"); var setInterceptedType = invocationType.GetMethod("set_InterceptedType"); var setInterceptedInstance = invocationType.GetMethod("set_InterceptedInstance"); var setParameters = invocationType.GetMethod("set_Parameters"); var setValue = parameterType.GetMethod("set_Value"); var getValue = parameterType.GetMethod("get_Value"); var setName = parameterType.GetMethod("set_Name"); var setParameterInfo = parameterType.GetMethod("set_ParameterInfo"); var getName = typeof(ParameterInfo).GetMethod("get_Name"); var getParameterInterceptors = typeof(InterceptorExtends).GetMethod("GetParameterInterceptors"); var getCurrentParameter = typeof(InterceptorExtends).GetMethod("GetCurrentParameter"); var onIntercept = typeof(IParameterInterceptor).GetMethod("OnParameterExecuting"); var interceptorLocal = ilGenerator.DeclareLocal(typeof(IParameterInterceptor[])); var parametersLocal = ilGenerator.DeclareLocal(typeof(IParameter[])); ilGenerator.LoadLocal(local[0]).Call(getParameterInterceptors).StoreLocal(interceptorLocal); var invocationLocal = ilGenerator.DeclareLocal(invocationType); ilGenerator.New(invocationType.GetConstructor(Type.EmptyTypes)).StoreLocal(invocationLocal); ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[1]).Callvirt(setInterceptedMethod); ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[2]).Callvirt(setInterceptedType); ilGenerator.LoadLocal(invocationLocal).This().Callvirt(setInterceptedInstance); ilGenerator.ForEach(parameterInterceptors, (_, interceptor, i) => { var parameters = method.GetParameters().Where(p => p.GetCustomAttributes(false).Any(c => c.GetType() == interceptor.GetType())).ToArray(); ilGenerator.NewArray(typeof(IParameter), parameters.Length).StoreLocal(parametersLocal); ilGenerator.ForEach(parameters, (__, parameter, j) => ilGenerator.ForEach(method.GetParameters(), (___, arg, k) => { if (arg == parameter) { var argLocal = ilGenerator.DeclareLocal(parameterType); ilGenerator.New(parameterType.GetConstructor(Type.EmptyTypes)).StoreLocal(argLocal); ilGenerator.LoadLocal(argLocal).LoadArgument(k + 1).Box(arg.ParameterType).Callvirt(setValue); ilGenerator.LoadLocal(argLocal).LoadLocal(local[1]).LoadInt(k).Call(getCurrentParameter).Callvirt(setParameterInfo); ilGenerator.LoadLocal(argLocal).LoadLocal(local[1]).LoadInt(k).Call(getCurrentParameter).Callvirt(getName).Callvirt(setName); ilGenerator.LoadLocal(parametersLocal).LoadInt(j).LoadLocal(argLocal).SetArrayItemRef(); } })); ilGenerator.LoadLocal(invocationLocal).LoadLocal(parametersLocal).Callvirt(setParameters); ilGenerator.LoadLocal(interceptorLocal).LoadArrayItem(i).LoadLocal(invocationLocal).Callvirt(onIntercept); ilGenerator.ForEach(parameters, (__, parameter, j) => ilGenerator.ForEach(method.GetParameters(), (___, arg, k) => { if (arg == parameter) { ilGenerator.LoadLocal(parametersLocal).LoadArrayItem(j).Callvirt(getValue).UnBox(arg.ParameterType).StroeArgument(k + 1); } })); }); }