private void AddVoidMethodImplementation( TypeBuilder classBuilder, int interfaceDescriptionId, MethodDescription methodDescription, MethodBodyTypes methodBodyTypes, string interfaceName) { var interfaceMethod = methodDescription.MethodInfo; var methodBuilder = CodeBuilderUtils.CreateExplitInterfaceMethodBuilder( classBuilder, interfaceMethod); var ilGen = methodBuilder.GetILGenerator(); // Create Wrapped Request LocalBuilder wrappedRequestBody = CreateWrappedRequestBody(methodDescription, methodBodyTypes, ilGen, methodDescription.MethodInfo.GetParameters()); this.AddVoidMethodImplementation( ilGen, interfaceDescriptionId, methodDescription, wrappedRequestBody, interfaceName); ilGen.Emit(OpCodes.Ret); }
private void AddAsyncMethodImplementation( TypeBuilder classBuilder, int interfaceId, MethodDescription methodDescription, MethodBodyTypes methodBodyTypes, string interfaceName) { var interfaceMethod = methodDescription.MethodInfo; var parameters = interfaceMethod.GetParameters(); var methodBuilder = CodeBuilderUtils.CreateExplitInterfaceMethodBuilder( classBuilder, interfaceMethod); var ilGen = methodBuilder.GetILGenerator(); var parameterLength = parameters.Length; if (methodDescription.HasCancellationToken) { // Cancellation token is tracked locally and should not be serialized and sent // as a part of the request body. parameterLength -= 1; } LocalBuilder requestMessage = null; if (parameterLength > 0) { // Create Wrapped Message // create requestBody and assign the values to its field from the arguments var wrappedRequestBody = CreateWrappedRequestBody(methodDescription, methodBodyTypes, ilGen, parameters); // create IServiceRemotingRequestMessageBody message requestMessage = this.CreateRequestRemotingMessageBody(methodDescription, interfaceName, ilGen, parameterLength, wrappedRequestBody); // Check if requestMessage is not implementing WrappedMessage , then call SetParam this.SetParameterIfNeeded(ilGen, requestMessage, parameterLength, parameters); } var objectTask = ilGen.DeclareLocal(typeof(Task <IActorResponseMessageBody>)); // call the base InvokeMethodAsync method ilGen.Emit(OpCodes.Ldarg_0); // base ilGen.Emit(OpCodes.Ldc_I4, interfaceId); // interfaceId ilGen.Emit(OpCodes.Ldc_I4, methodDescription.Id); // methodId ilGen.Emit(OpCodes.Ldstr, methodDescription.Name); // method name if (requestMessage != null) { ilGen.Emit(OpCodes.Ldloc, requestMessage); } else { ilGen.Emit(OpCodes.Ldnull); } // Cancellation token argument if (methodDescription.HasCancellationToken) { // Last argument should be the cancellation token var cancellationTokenArgIndex = parameters.Length; ilGen.Emit(OpCodes.Ldarg, cancellationTokenArgIndex); } else { var cancellationTokenNone = typeof(CancellationToken).GetMethod("get_None"); ilGen.EmitCall(OpCodes.Call, cancellationTokenNone, null); } ilGen.EmitCall(OpCodes.Call, this.invokeAsyncMethodInfo, null); ilGen.Emit(OpCodes.Stloc, objectTask); // call the base method to get the continuation task and // convert the response body to return value when the task is finished if (TypeUtility.IsTaskType(methodDescription.ReturnType) && methodDescription.ReturnType.GetTypeInfo().IsGenericType) { var retvalType = methodDescription.ReturnType.GetGenericArguments()[0]; ilGen.Emit(OpCodes.Ldarg_0); // base pointer ilGen.Emit(OpCodes.Ldc_I4, interfaceId); // interfaceId ilGen.Emit(OpCodes.Ldc_I4, methodDescription.Id); // methodId ilGen.Emit(OpCodes.Ldloc, objectTask); // task<IServiceRemotingResponseMessageBody> ilGen.Emit(OpCodes.Call, this.continueWithResultMethodInfo.MakeGenericMethod(retvalType)); ilGen.Emit(OpCodes.Ret); // return base.ContinueWithResult<TResult>(task); } else { ilGen.Emit(OpCodes.Ldarg_0); // base pointer ilGen.Emit(OpCodes.Ldloc, objectTask); // task<object> ilGen.Emit(OpCodes.Call, this.continueWithMethodInfo); ilGen.Emit(OpCodes.Ret); // return base.ContinueWith(task); } }