public void UpdateKnownTypeDetail(InterfaceDescription interfaceDescription, MethodBodyTypesBuildResult methodBodyTypesBuildResult) { var responseKnownTypes = new List <Type>(); var requestKnownType = new List <Type>(); foreach (var entry in interfaceDescription.Methods) { if (TypeUtility.IsTaskType(entry.ReturnType) && entry.ReturnType.GetTypeInfo().IsGenericType) { var returnType = entry.MethodInfo.ReturnType.GetGenericArguments()[0]; if (!responseKnownTypes.Contains(returnType)) { responseKnownTypes.Add(returnType); } } requestKnownType.AddRange(entry.MethodInfo.GetParameters() .ToList() .Select(p => p.ParameterType) .Except(requestKnownType)); } var knownType = new InterfaceDetails { Id = interfaceDescription.Id, ServiceInterfaceType = interfaceDescription.InterfaceType, RequestKnownTypes = requestKnownType, ResponseKnownTypes = responseKnownTypes, MethodNames = interfaceDescription.Methods.ToDictionary(item => item.Name, item => item.Id), RequestWrappedKnownTypes = methodBodyTypesBuildResult.GetRequestBodyTypes(), ResponseWrappedKnownTypes = methodBodyTypesBuildResult.GetResponseBodyTypes(), }; this.UpdateKnownTypes(interfaceDescription.Id, interfaceDescription.InterfaceType.FullName, knownType); }
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)); }
public MethodBodyTypesBuildResult Build(InterfaceDescription interfaceDescription) { var context = new CodeBuilderContext( assemblyName: this.CodeBuilder.Names.GetMethodBodyTypesAssemblyName(interfaceDescription.InterfaceType), assemblyNamespace: this.CodeBuilder.Names.GetMethodBodyTypesAssemblyNamespace(interfaceDescription.InterfaceType), enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(interfaceDescription.InterfaceType)); var result = new MethodBodyTypesBuildResult(context) { MethodBodyTypesMap = new Dictionary <string, MethodBodyTypes>(), }; foreach (var method in interfaceDescription.Methods) { result.MethodBodyTypesMap.Add( method.Name, Build(this.CodeBuilder.Names, context, method)); } context.Complete(); return(result); }
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); }