예제 #1
0
        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);
        }
예제 #2
0
        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]);
            }
        }
예제 #3
0
        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);
                    }
                }));
            });
        }