示例#1
0
        private void AddOnDispatchAsyncMethod(
            TypeBuilder classBuilder,
            InterfaceDescription interfaceDescription,
            MethodBodyTypesBuildResult methodBodyTypesBuildResult)
        {
            var dispatchMethodImpl = CodeBuilderUtils.CreateProtectedMethodBuilder(
                classBuilder,
                "OnDispatchAsync",
                typeof(Task <object>),
                typeof(int),                // methodid
                typeof(object),             // remoted object
                typeof(object),             // requestBody
                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,
                    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);
        }
示例#3
0
        private void AddCreateResponseBodyMethod(
            TypeBuilder classBuilder,
            InterfaceDescription interfaceDescription,
            MethodBodyTypesBuildResult methodBodyTypesBuildResult)
        {
            var methodBuilder = CodeBuilderUtils.CreateProtectedMethodBuilder(
                classBuilder,
                "CreateResponseBody",
                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);
        }