コード例 #1
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);
             }
         }));
     });
 }