private void BuildServiceMethodBody(ILGenerator ilGenerator, ServiceMethodInfo serviceMethodInfo) { //确定需要调用的方法 var invokeMethod = serviceMethodInfo.IsAsyncMode ? GetServiceInvokeAsyncMethod(serviceMethodInfo) : GetServiceInvokeMethod(serviceMethodInfo); //确定方法参数 var parameter = serviceMethodInfo.ParameterNameVisibility == ParameterNameVisibility.Hidden ? GetServiceParameterByObject(ilGenerator, serviceMethodInfo) : GetServiceParameterByDictionary(ilGenerator, serviceMethodInfo); //进行方法调用 ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldstr, serviceMethodInfo.SysName); ilGenerator.Emit(OpCodes.Ldstr, serviceMethodInfo.TransactionCode); ilGenerator.Emit(OpCodes.Ldloc, parameter); ilGenerator.Emit(IsFakeMode(serviceMethodInfo.ServiceMethod) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); if (serviceMethodInfo.IsAsyncMode) { ilGenerator.Emit(OpCodes.Ldarg, serviceMethodInfo.Parameters.Count + 1); if (serviceMethodInfo.OnErrorCallback != null) { ilGenerator.Emit(OpCodes.Ldarg, serviceMethodInfo.Parameters.Count + 2); } else { ilGenerator.Emit(OpCodes.Ldnull); } } ilGenerator.Emit(OpCodes.Callvirt, invokeMethod); ilGenerator.Emit(OpCodes.Ret); }
/// <summary> /// 处理只有一个参数,且参数类型为引用类型(除string类型)的方式,此时直接对参数进行序列化 /// </summary> /// <param name="ilGenerator"></param> /// <param name="serviceMethodInfo"></param> /// <returns></returns> private LocalBuilder GetServiceParameterByObject(ILGenerator ilGenerator, ServiceMethodInfo serviceMethodInfo) { var parameter = ilGenerator.DeclareLocal(serviceMethodInfo.Parameters.First().ParameterType); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stloc, parameter); return(parameter); }
private void BuildServiceMethods() { foreach (var serviceMethod in serviceType.GetMethods()) { var serviceMethodInfo = new ServiceMethodInfo(serviceType, serviceMethod); serviceMethodInfo.Read(); var methodBuilder = DefineMethod(serviceMethod); var ilGenerator = methodBuilder.GetILGenerator(); BuildServiceMethodBody(ilGenerator, serviceMethodInfo); } }
/// <summary> /// 获取用于进行以异步方式进行服务调用的方法 /// </summary> /// <param name="serviceMethodInfo"></param> /// <returns></returns> private MethodInfo GetServiceInvokeAsyncMethod(ServiceMethodInfo serviceMethodInfo) { var invokeMethod = typeof(JavaServiceProxy).GetMethod( serviceMethodInfo.OnSuccessCallback.ParameterType.IsGenericType ? "InvokeGenericAsync" : "InvokeAsync", BindingFlags.NonPublic | BindingFlags.Instance); if (serviceMethodInfo.OnSuccessCallback.ParameterType.IsGenericType) { invokeMethod = invokeMethod.MakeGenericMethod(serviceMethodInfo.OnSuccessCallback.ParameterType.GetGenericArguments()); } return(invokeMethod); }
/// <summary> /// 获取用于进行以同步方式进行服务调用的方法 /// </summary> /// <param name="serviceMethodInfo"></param> /// <returns></returns> private MethodInfo GetServiceInvokeMethod(ServiceMethodInfo serviceMethodInfo) { var invokeMethod = typeof(JavaServiceProxy).GetMethod( serviceMethodInfo.ServiceMethod.ReturnType.IsGenericType ? "InvokeGeneric" : "Invoke", BindingFlags.NonPublic | BindingFlags.Instance); if (serviceMethodInfo.ServiceMethod.ReturnType.IsGenericType) { invokeMethod = invokeMethod.MakeGenericMethod(serviceMethodInfo.ServiceMethod.ReturnType.GetGenericArguments()); } return(invokeMethod); }
/// <summary> /// 处理含有任意个参数的方法,此时将所有参数添加到一个字典中,再进行序列化操作 /// </summary> /// <param name="ilGenerator"></param> /// <param name="serviceMethodInfo"></param> /// <returns></returns> private LocalBuilder GetServiceParameterByDictionary(ILGenerator ilGenerator, ServiceMethodInfo serviceMethodInfo) { var dictType = typeof(Dictionary <string, object>); var values = ilGenerator.DeclareLocal(dictType); //values = new Dictionary<string, object>(); ilGenerator.Emit(OpCodes.Newobj, dictType.GetConstructor(Type.EmptyTypes)); ilGenerator.Emit(OpCodes.Stloc, values); //将所有的参数添加到一个字典中 for (var i = 0; i < serviceMethodInfo.Parameters.Count; i++) { //values.Add(name, value); ilGenerator.Emit(OpCodes.Ldloc, values); ilGenerator.Emit(OpCodes.Ldstr, serviceMethodInfo.Parameters[i].Name); ilGenerator.Emit(OpCodes.Ldarg, i + 1); //对于值类型,进行装箱处理 if (serviceMethodInfo.Parameters[i].ParameterType.IsValueType) { ilGenerator.Emit(OpCodes.Box, serviceMethodInfo.Parameters[i].ParameterType); } ilGenerator.Emit(OpCodes.Callvirt, dictType.GetMethod("Add")); } return(values); }