Beispiel #1
0
        /// <summary>
        /// 通过反射调用指定方法
        /// </summary>
        /// <param name="method">方法</param>
        /// <param name="parameters">方法参数</param>
        /// <returns></returns>
        public object Invoke(MethodInfo method, object[] parameters)
        {
            object                service = kernel[method.DeclaringType];
            ISystemService        system  = (ISystemService)kernel[typeof(ISystemService)];
            DynamicInvokerHandler invoker = system.GetDynamicInvoker(method);

            return(invoker(service, parameters));
        }
Beispiel #2
0
 /// <summary>
 /// 获取方法的动态调用器
 /// </summary>
 /// <param name="method">The method.</param>
 /// <returns></returns>
 public DynamicInvokerHandler GetDynamicInvoker(MethodInfo method)
 {
     if (invokers.ContainsKey(method))
     {
         return(invokers[method]);
     }
     else
     {
         try {
             logger.Debug(String.Format("生成方法 \"{0}\" 的调用器", method));
             //if (method.IsGenericMethod)
             //    method = method.GetGenericMethodDefinition();
             DynamicInvokerHandler invoker = DynamicInvoker.GetMethodInvoker(method);
             invokers[method] = invoker;
             return(invoker);
         }
         catch (Exception ex) {
             throw ex;
         }
     }
 }
Beispiel #3
0
        private void InvokeMehtod(object target, MethodInfo method, EventArgs e)
        {
            DynamicInvokerHandler invoker = DynamicInvoker.GetMethodInvoker(method);

            invoker(target, new object[] { null, e });
        }
Beispiel #4
0
        /// <summary>
        /// 获取方法定义的快速调用器
        /// </summary>
        /// <param name="methodInfo">方法信息</param>
        /// <returns>快速调用委托<see cref="FastInvokeHandler"/></returns>
        public static DynamicInvokerHandler GetMethodInvoker(MethodInfo methodInfo)
        {
            DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object),
                                                            new Type[] { typeof(object), typeof(object[]) },
                                                            methodInfo.DeclaringType.Module);
            ILGenerator il = dynamicMethod.GetILGenerator();

            // 获取方法参数信息
            ParameterInfo[] ps = methodInfo.GetParameters();
            if (!methodInfo.IsGenericMethod)
            {
                Type[] paramTypes = new Type[ps.Length];
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    if (ps[i].ParameterType.IsByRef)
                    {
                        paramTypes[i] = ps[i].ParameterType.GetElementType();
                    }
                    else
                    {
                        paramTypes[i] = ps[i].ParameterType;
                    }
                }
                LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];

                // 为每个参数生成本地变量
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    locals[i] = il.DeclareLocal(paramTypes[i], true);
                }
                // 将方法类型信息转存到本地变量中
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    il.Emit(OpCodes.Ldarg_1);
                    EmitFastInt(il, i);
                    il.Emit(OpCodes.Ldelem_Ref);
                    EmitCastToReference(il, paramTypes[i]);
                    il.Emit(OpCodes.Stloc, locals[i]);
                }

                // 对象入栈
                if (!methodInfo.IsStatic)
                {
                    il.Emit(OpCodes.Ldarg_0);
                }

                // 将方法参数的本地副本入栈
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    if (ps[i].ParameterType.IsByRef)
                    {
                        il.Emit(OpCodes.Ldloca_S, locals[i]);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldloc, locals[i]);
                    }
                }

                // Call method
                EmitCall(il, methodInfo);

                if (methodInfo.ReturnType == typeof(void))
                {
                    il.Emit(OpCodes.Ldnull);
                }
                else
                {
                    EmitBoxIfNeeded(il, methodInfo.ReturnType);
                }

                // 更新引用类参数以保证其可以正确返回
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    if (ps[i].ParameterType.IsByRef)
                    {
                        il.Emit(OpCodes.Ldarg_1);
                        EmitFastInt(il, i);
                        il.Emit(OpCodes.Ldloc, locals[i]);
                        if (locals[i].LocalType.IsValueType)
                        {
                            il.Emit(OpCodes.Box, locals[i].LocalType);
                        }
                        il.Emit(OpCodes.Stelem_Ref);
                    }
                }

                // 返回
                il.Emit(OpCodes.Ret);
            }
            else
            {
                // define local vars
                il.DeclareLocal(typeof(object));

                // load first argument, the instace where the method is to be invoked
                il.Emit(OpCodes.Ldarg_0);

                // cast to the correct type
                il.Emit(OpCodes.Castclass, methodInfo.DeclaringType);

                for (int i = 0; i < ps.Length; i++)
                {
                    // load paramters they are passed as an object array
                    il.Emit(OpCodes.Ldarg_1);

                    // load array element
                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldelem_Ref);

                    // cast or unbox parameter as needed
                    Type parameterType = ps[i].ParameterType;
                    if (parameterType.IsClass)
                    {
                        il.Emit(OpCodes.Castclass, parameterType);
                    }
                    else
                    {
                        il.Emit(OpCodes.Unbox_Any, parameterType);
                    }
                }

                // call method
                EmitCall(il, methodInfo);

                // handle method return if needed
                if (methodInfo.ReturnType == typeof(void))
                {
                    // return null
                    il.Emit(OpCodes.Ldnull);
                }
                else
                {
                    // box value if needed
                    if (methodInfo.ReturnType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, methodInfo.ReturnType);
                    }
                }

                // store to the local var
                il.Emit(OpCodes.Stloc_0);

                // load local and return
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ret);
            }
            DynamicInvokerHandler invoker = (DynamicInvokerHandler)dynamicMethod.CreateDelegate(typeof(DynamicInvokerHandler));

            return(invoker);
        }