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); }
public CodeBuilderContext(string assemblyName, string assemblyNamespace, bool enableDebugging = false) { this.AssemblyNamespace = assemblyNamespace; this.enableDebugging = enableDebugging; this.AssemblyBuilder = CodeBuilderUtils.CreateAssemblyBuilder(assemblyName, this.enableDebugging); this.ModuleBuilder = CodeBuilderUtils.CreateModuleBuilder(this.AssemblyBuilder, assemblyName, this.enableDebugging); }
private Type BuildProxyActivatorType( CodeBuilderContext context, Type proxyInterfaceType, Type proxyType) { var classBuilder = CodeBuilderUtils.CreateClassBuilder( context.ModuleBuilder, ns: context.AssemblyNamespace, className: this.CodeBuilder.Names.GetProxyActivatorClassName(proxyInterfaceType), interfaces: new[] { typeof(IProxyActivator) }); AddCreateInstanceMethod(classBuilder, proxyType); return(classBuilder.CreateTypeInfo().AsType()); }
private Type BuildProxyType( CodeBuilderContext context, Type proxyInterfaceType, IDictionary <InterfaceDescription, MethodBodyTypesBuildResult> methodBodyTypesResultsMap) { var classBuilder = CodeBuilderUtils.CreateClassBuilder( context.ModuleBuilder, ns: context.AssemblyNamespace, className: this.CodeBuilder.Names.GetProxyClassName(proxyInterfaceType), baseType: this.proxyBaseType, interfaces: methodBodyTypesResultsMap.Select(item => item.Key.InterfaceType).ToArray()); this.AddGetReturnValueMethod(classBuilder, methodBodyTypesResultsMap); this.AddInterfaceImplementations(classBuilder, methodBodyTypesResultsMap); return(classBuilder.CreateTypeInfo().AsType()); }
private void AddOnDispatchAsyncMethod( TypeBuilder classBuilder, InterfaceDescription interfaceDescription, MethodBodyTypesBuildResult methodBodyTypesBuildResult) { var dispatchMethodImpl = CodeBuilderUtils.CreateProtectedMethodBuilder( classBuilder, "OnDispatchAsync", typeof(Task <IActorResponseMessageBody>), typeof(int), // methodid typeof(object), // remoted object typeof(IActorRequestMessageBody), // requestBody typeof(IActorMessageBodyFactory), // remotingmessageBodyFactory typeof(CancellationToken)); // CancellationToken var ilGen = dispatchMethodImpl.GetILGenerator(); var castedObject = ilGen.DeclareLocal(interfaceDescription.InterfaceType); ilGen.Emit(OpCodes.Ldarg_2); // load remoted object ilGen.Emit(OpCodes.Castclass, interfaceDescription.InterfaceType); ilGen.Emit(OpCodes.Stloc, castedObject); // store casted result to local 0 foreach (var methodDescription in interfaceDescription.Methods) { if (!TypeUtility.IsTaskType(methodDescription.ReturnType)) { continue; } var elseLable = ilGen.DefineLabel(); this.AddIfMethodIdInvokeAsyncBlock( ilGen: ilGen, elseLabel: elseLable, castedObject: castedObject, methodDescription: methodDescription, interfaceName: interfaceDescription.InterfaceType.FullName, methodBodyTypes: methodBodyTypesBuildResult.MethodBodyTypesMap[methodDescription.Name]); ilGen.MarkLabel(elseLable); } ilGen.ThrowException(typeof(MissingMethodException)); }
private void AddGetReturnValueMethod( TypeBuilder classBuilder, IDictionary <InterfaceDescription, MethodBodyTypesBuildResult> methodBodyTypesResultsMap) { var methodBuilder = CodeBuilderUtils.CreateProtectedMethodBuilder( classBuilder, "GetReturnValue", typeof(object), // return value from the reponseBody typeof(int), // interfaceId typeof(int), // methodId typeof(object)); // responseBody var ilGen = methodBuilder.GetILGenerator(); foreach (var item in methodBodyTypesResultsMap) { var interfaceDescription = item.Key; var methodBodyTypesMap = item.Value.MethodBodyTypesMap; foreach (var methodDescription in interfaceDescription.Methods) { var methodBodyTypes = methodBodyTypesMap[methodDescription.Name]; if (methodBodyTypes.ResponseBodyType == null) { continue; } var elseLabel = ilGen.DefineLabel(); this.AddIfInterfaceIdAndMethodIdReturnRetvalBlock( ilGen, elseLabel, interfaceDescription.Id, methodDescription.Id, methodBodyTypes.ResponseBodyType); ilGen.MarkLabel(elseLabel); } } // return null; (if method id's and interfaceId do not mGetReturnValueatch) ilGen.Emit(OpCodes.Ldnull); ilGen.Emit(OpCodes.Ret); }
private static Type BuildResponseBodyType( ICodeBuilderNames codeBuilderNames, CodeBuilderContext context, MethodDescription methodDescription) { var responseBodyTypeBuilder = CodeBuilderUtils.CreateDataContractTypeBuilder( moduleBuilder: context.ModuleBuilder, ns: context.AssemblyNamespace, typeName: codeBuilderNames.GetResponseBodyTypeName(methodDescription.Name), dcNamespace: codeBuilderNames.GetDataContractNamespace()); var returnDataType = methodDescription.ReturnType.GetGenericArguments()[0]; CodeBuilderUtils.AddDataMemberField( dcTypeBuilder: responseBodyTypeBuilder, fieldType: returnDataType, fieldName: codeBuilderNames.RetVal); return(responseBodyTypeBuilder.CreateTypeInfo().AsType()); }
private static Type BuildRequestBodyType( ICodeBuilderNames codeBuilderNames, CodeBuilderContext context, MethodDescription methodDescription) { var requestBodyTypeBuilder = CodeBuilderUtils.CreateDataContractTypeBuilder( moduleBuilder: context.ModuleBuilder, ns: context.AssemblyNamespace, typeName: codeBuilderNames.GetRequestBodyTypeName(methodDescription.Name), dcNamespace: codeBuilderNames.GetDataContractNamespace()); foreach (var argument in methodDescription.Arguments) { CodeBuilderUtils.AddDataMemberField( dcTypeBuilder: requestBodyTypeBuilder, fieldType: argument.ArgumentType, fieldName: argument.Name); } return(requestBodyTypeBuilder.CreateTypeInfo().AsType()); }
public MethodDispatcherBuildResult Build( InterfaceDescription interfaceDescription) { var context = new CodeBuilderContext( assemblyName: this.CodeBuilder.Names.GetMethodDispatcherAssemblyName(interfaceDescription.InterfaceType), assemblyNamespace: this.CodeBuilder.Names.GetMethodDispatcherAssemblyNamespace(interfaceDescription .InterfaceType), enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(interfaceDescription.InterfaceType)); var result = new MethodDispatcherBuildResult(context); // ensure that the method body types are built var methodBodyTypesBuildResult = this.CodeBuilder.GetOrBuildMethodBodyTypes(interfaceDescription.InterfaceType); // build dispatcher class var classBuilder = CodeBuilderUtils.CreateClassBuilder( context.ModuleBuilder, ns: context.AssemblyNamespace, className: this.CodeBuilder.Names.GetMethodDispatcherClassName(interfaceDescription.InterfaceType), baseType: this.methodDispatcherBaseType); this.AddCreateResponseBodyMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult); this.AddOnDispatchAsyncMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult); this.AddOnDispatchMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult); var methodNameMap = GetMethodNameMap(interfaceDescription); // create the dispatcher type, instantiate and initialize it result.MethodDispatcherType = classBuilder.CreateTypeInfo().AsType(); result.MethodDispatcher = (TMethodDispatcher)Activator.CreateInstance(result.MethodDispatcherType); var v2MethodDispatcherBase = (ActorMethodDispatcherBase)result.MethodDispatcher; v2MethodDispatcherBase.Initialize(interfaceDescription, methodNameMap); context.Complete(); return(result); }
private static void AddCreateInstanceMethod( TypeBuilder classBuilder, Type proxyType) { var methodBuilder = CodeBuilderUtils.CreatePublicMethodBuilder( classBuilder, "CreateInstance", typeof(IActorProxy)); var ilGen = methodBuilder.GetILGenerator(); var proxyCtor = proxyType.GetConstructor(Type.EmptyTypes); if (proxyCtor != null) { ilGen.Emit(OpCodes.Newobj, proxyCtor); ilGen.Emit(OpCodes.Ret); } else { ilGen.Emit(OpCodes.Ldnull); ilGen.Emit(OpCodes.Ret); } }
private void AddCreateResponseBodyMethod( TypeBuilder classBuilder, InterfaceDescription interfaceDescription, MethodBodyTypesBuildResult methodBodyTypesBuildResult) { var methodBuilder = CodeBuilderUtils.CreateProtectedMethodBuilder( classBuilder, "CreateWrappedResponseBody", typeof(object), // responseBody - return value typeof(int), // methodId typeof(object)); // retval from the invoked method on the remoted object var ilGen = methodBuilder.GetILGenerator(); foreach (var methodDescription in interfaceDescription.Methods) { var methodBodyTypes = methodBodyTypesBuildResult.MethodBodyTypesMap[methodDescription.Name]; if (methodBodyTypes.ResponseBodyType == null) { continue; } var elseLabel = ilGen.DefineLabel(); this.AddIfMethodIdCreateResponseBlock( ilGen, elseLabel, methodDescription.Id, methodBodyTypes.ResponseBodyType); ilGen.MarkLabel(elseLabel); } // return null; (if method id's do not match) ilGen.Emit(OpCodes.Ldnull); 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); } }