/// <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)); }
/// <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; } } }
private void InvokeMehtod(object target, MethodInfo method, EventArgs e) { DynamicInvokerHandler invoker = DynamicInvoker.GetMethodInvoker(method); invoker(target, new object[] { null, e }); }
/// <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); }