Beispiel #1
0
        private MethodBuilder BuildMethodAsync(TypeBuilder type, MethodInfo serviceAction)
        {
            const MethodAttributes methodAttributes = MethodAttributes.Public
                                                      | MethodAttributes.Virtual
                                                      | MethodAttributes.Final
                                                      | MethodAttributes.HideBySig
                                                      | MethodAttributes.NewSlot;
            var method = type.DefineMethod(serviceAction.Name, methodAttributes);
            // Preparing Reflection instances
            var method1 = typeof(RestWrapper).GetMethod(
                "GetParameters",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new[] {
                typeof(string),
                typeof(object[])
            },
                null
                );

            var method2 = typeof(RestWrapper).GetMethod(serviceAction.ReturnType.GetGenericArguments().Length == 0 ? "InvokeVoidAsync" : "InvokeAsync", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(string), typeof(ParameterWrapper[]) }, null);

            if (serviceAction.ReturnType.GenericTypeArguments.Any())
            {
                method2 = method2.MakeGenericMethod(serviceAction.ReturnType.GenericTypeArguments);
            }


            // Setting return type

            method.SetReturnType(serviceAction.ReturnType);
            // Adding parameters
            method.SetParameters(serviceAction.GetParameters().Select(p => p.ParameterType).ToArray());
            var i = 1;

            foreach (var parameterInfo in serviceAction.GetParameters())
            {
                var param = method.DefineParameter(i, ParameterAttributes.None, parameterInfo.Name);
                i++;
            }
            ILGenerator gen = method.GetILGenerator();
            // Preparing locals
            LocalBuilder par        = gen.DeclareLocal(typeof(Object[]));
            LocalBuilder parameters = gen.DeclareLocal(typeof(ParameterWrapper[]));
            LocalBuilder result     = gen.DeclareLocal(serviceAction.ReturnType);
            LocalBuilder str        = gen.DeclareLocal(serviceAction.ReturnType);
            // Preparing labels
            Label label55 = gen.DefineLabel();
            // Writing body
            var ps = serviceAction.GetParameters();

            EmitHelpers.EmitInt32(gen, ps.Length);
            gen.Emit(OpCodes.Newarr, typeof(object));
            for (int j = 0; j < ps.Length; j++)
            {
                gen.Emit(OpCodes.Dup);
                EmitHelpers.EmitInt32(gen, j);
                EmitHelpers.EmitLdarg(gen, j + 1);
                var paramType = ps[j].ParameterType;
                if (paramType.IsValueType)
                {
                    gen.Emit(OpCodes.Box, paramType);
                }
                gen.Emit(OpCodes.Stelem_Ref);
            }
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, serviceAction.Name);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Call, method1);
            gen.Emit(OpCodes.Stloc_1);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, serviceAction.Name);
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Call, method2);
            gen.Emit(OpCodes.Stloc_2);
            gen.Emit(OpCodes.Ldloc_2);
            gen.Emit(OpCodes.Stloc_3);
            gen.Emit(OpCodes.Br_S, label55);
            gen.MarkLabel(label55);
            gen.Emit(OpCodes.Ldloc_3);
            gen.Emit(OpCodes.Ret);
            // finished
            return(method);
        }
Beispiel #2
0
        private MethodBuilder BuildAsyncVoidMethodBody(MethodInfo implementationMethod, MethodBuilder method, Type[] pTypes, List <ParameterWrapper> methodParams, TypeBuilder parent)
        {
            MethodInfo gatherParams = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod(
                "GatherParameters",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(string),
                typeof(object[])
            },
                null
                );
            var        delegateType   = new VoidDelegateBuilder(myModuleBuilder).CreateVoidDelegate(implementationMethod, parent, methodParams);
            var        delegateCtor   = delegateType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);
            var        baseType       = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType);
            var        implementation = baseType.GetRuntimeFields().Single(f => f.Name == "implementation");
            MethodInfo getValue       = typeof(ParameterWrapper).GetMethod(
                "get_value",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
            },
                null
                );
            ConstructorInfo ctor9 = typeof(System.Func <>).MakeGenericType(typeof(Task)).GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(Object),
                typeof(IntPtr)
            },
                null
                );

            MethodInfo createResponse = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod("CreateResponseAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            //createResponse = createResponse.MakeGenericMethod(implementationMethod.ReturnType.GetGenericArguments());
            MethodInfo method9 = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod(
                "CreateErrorResponse",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(Exception)
            },
                null
                );

            var delegateMethod = delegateType.GetMethod(implementationMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);//.MakeGenericMethod(implementationMethod.ReturnType.GenericTypeArguments);
            var method10       = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType)
                                 .GetMethod("ExecuteMethodVoidAsync", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo field7 = delegateType.GetField("parameters", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            FieldInfo field5 = delegateType.GetField("implementation", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            MethodInfo  fromResult = typeof(Task).GetMethod("FromResult").MakeGenericMethod(typeof(IActionResult));
            ILGenerator gen        = method.GetILGenerator();
            // Preparing locals
            LocalBuilder del = gen.DeclareLocal(delegateType);
            LocalBuilder serviceParameters = gen.DeclareLocal(typeof(object[]));
            LocalBuilder result            = gen.DeclareLocal(typeof(Task <>).MakeGenericType(typeof(IActionResult)));
            LocalBuilder ex = gen.DeclareLocal(typeof(Exception));
            // Preparing labels
            Label label97 = gen.DefineLabel();

            // Writing body
            gen.Emit(OpCodes.Nop);
            gen.BeginExceptionBlock();
            gen.Emit(OpCodes.Newobj, delegateCtor);
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Stfld, field5);
            var ps = pTypes;

            EmitHelpers.EmitInt32(gen, ps.Length);
            gen.Emit(OpCodes.Newarr, typeof(object));
            for (int j = 0; j < ps.Length; j++)
            {
                gen.Emit(OpCodes.Dup);
                EmitHelpers.EmitInt32(gen, j);
                EmitHelpers.EmitLdarg(gen, j + 1);
                var paramType = ps[j];
                if (paramType.IsValueType)
                {
                    gen.Emit(OpCodes.Box, paramType);
                }
                gen.Emit(OpCodes.Stelem_Ref);
            }
            gen.Emit(OpCodes.Stloc_1);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, implementationMethod.Name);
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Call, gatherParams);

            gen.Emit(OpCodes.Stfld, field7);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldftn, delegateMethod);
            gen.Emit(OpCodes.Newobj, ctor9);
            gen.Emit(OpCodes.Call, method10);
            gen.Emit(OpCodes.Stloc_2);
            gen.Emit(OpCodes.Leave_S, label97);
            gen.Emit(OpCodes.Leave_S, label97);
            gen.BeginCatchBlock(typeof(Exception));
            gen.Emit(OpCodes.Stloc_S, 3);
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloc_S, 3);
            gen.Emit(OpCodes.Call, method9);
            gen.Emit(OpCodes.Call, fromResult);
            gen.Emit(OpCodes.Stloc_2);
            gen.Emit(OpCodes.Leave_S, label97);
            gen.EndExceptionBlock();
            gen.MarkLabel(label97);
            gen.Emit(OpCodes.Ldloc_2);
            gen.Emit(OpCodes.Ret);
            // finished
            return(method);
        }
        public MethodBuilder BuildAsyncVoidMethod(TypeBuilder type, MethodInfo implementationMethod)
        {
            // Declaring method builder
            // Method attributes
            const MethodAttributes methodAttributes = MethodAttributes.Public
                                                      | MethodAttributes.Virtual
                                                      | MethodAttributes.Final
                                                      | MethodAttributes.HideBySig
                                                      | MethodAttributes.NewSlot;
            var method = type.DefineMethod(implementationMethod.Name, methodAttributes);

            // Preparing Reflection instances
            #region MyRegion
            ConstructorInfo route = typeof(RouteAttribute).GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(String)
            },
                null
                );
            ConstructorInfo httpGet   = httpMethodAttribute(implementationMethod);
            ConstructorInfo uriAttrib = typeof(FromUriAttribute).GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
            },
                null
                );
            ConstructorInfo bodyAttrib = typeof(FromBodyAttribute).GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
            },
                null
                );
            MethodInfo gatherParams = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod(
                "GatherParameters",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(string),
                typeof(object[])
            },
                null
                );
            var        baseType       = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType);
            var        implementation = baseType.GetRuntimeFields().Single(f => f.Name == "implementation");
            MethodInfo getValue       = typeof(ParameterWrapper).GetMethod(
                "get_value",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
            },
                null
                );
            MethodInfo createResponse = baseType.GetMethod("CreateResponseVoidAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            MethodInfo method9        = baseType.GetMethod(
                "CreateErrorResponse",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(Exception)
            },
                null
                );
            MethodInfo fromResult = typeof(Task).GetMethod("FromResult").MakeGenericMethod(typeof(HttpResponseMessage));

            #endregion

            // Setting return type
            method.SetReturnType(typeof(Task <HttpResponseMessage>));
            // Adding parameters
            var methodParams = new List <ParameterWrapper>();
            foreach (var parameterInfo in implementationMethod.GetParameters())
            {
                var @in = parameterInfo.GetCustomAttribute <InAttribute>(true);
                if (@in == null)
                {
                    var fromBody = parameterInfo.GetCustomAttribute <FromBodyAttribute>(true);
                    if (fromBody != null)
                    {
                        @in = new InAttribute(InclutionTypes.Body);
                    }
                    if (@in == null)
                    {
                        var fromUri = parameterInfo.GetCustomAttribute <FromUriAttribute>(true);
                        if (fromUri != null)
                        {
                            @in = new InAttribute(InclutionTypes.Path);
                        }
                    }
                }
                if (@in.InclutionType != InclutionTypes.Header)
                {
                    methodParams.Add(new ParameterWrapper {
                        Name = parameterInfo.Name, Type = parameterInfo.ParameterType, In = @in?.InclutionType ?? InclutionTypes.Body
                    });
                }
            }
            var pTypes = methodParams.Select(p => p.Type).ToArray();
            method.SetParameters(pTypes.ToArray());
            // Parameter id
            int pid = 1;
            foreach (var parameterWrapper in methodParams)
            {
                try
                {
                    var p = method.DefineParameter(pid, ParameterAttributes.None, parameterWrapper.Name);
                    if (parameterWrapper.In == InclutionTypes.Path)
                    {
                        p.SetCustomAttribute(new CustomAttributeBuilder(uriAttrib, new Type[] { }));
                    }
                    else if (parameterWrapper.In == InclutionTypes.Body)
                    {
                        p.SetCustomAttribute(new CustomAttributeBuilder(bodyAttrib, new Type[] { }));
                    }
                    pid++;
                }
                catch (Exception)
                {
                    throw;
                }
            }
            // Adding custom attributes to method
            // [RouteAttribute]
            method.SetCustomAttribute(
                new CustomAttributeBuilder(
                    route,
                    new[] {
                implementationMethod.GetCustomAttribute <RouteAttribute>().Template
            }
                    )
                );
            method.SetCustomAttribute(
                new CustomAttributeBuilder(
                    httpGet,
                    new Type[] { }
                    )
                );
            ILGenerator gen = method.GetILGenerator();
            // Preparing locals
            LocalBuilder parameters        = gen.DeclareLocal(typeof(Object[]));
            LocalBuilder serviceParameters = gen.DeclareLocal(typeof(ParameterWrapper[]));
            LocalBuilder result            = gen.DeclareLocal(typeof(Task));
            LocalBuilder message           = gen.DeclareLocal(typeof(Task <HttpResponseMessage>));
            LocalBuilder ex = gen.DeclareLocal(typeof(Exception));
            // Preparing labels
            // Writing body
            gen.Emit(OpCodes.Nop);
            gen.BeginExceptionBlock();
            gen.Emit(OpCodes.Nop);
            var ps = pTypes;
            EmitHelpers.EmitInt32(gen, ps.Length);
            gen.Emit(OpCodes.Newarr, typeof(object));
            for (int j = 0; j < ps.Length; j++)
            {
                gen.Emit(OpCodes.Dup);
                EmitHelpers.EmitInt32(gen, j);
                EmitHelpers.EmitLdarg(gen, j + 1);
                var paramType = ps[j];
                if (paramType.IsValueType)
                {
                    gen.Emit(OpCodes.Box, paramType);
                }
                gen.Emit(OpCodes.Stelem_Ref);
            }
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, implementationMethod.Name);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Call, gatherParams);
            gen.Emit(OpCodes.Stloc_1);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, implementation);
            int iii = 0;
            foreach (var parameterWrapper in methodParams)
            {
                gen.Emit(OpCodes.Ldloc_1);
                EmitHelpers.EmitInt32(gen, iii);
                gen.Emit(OpCodes.Ldelem_Ref);
                gen.Emit(OpCodes.Callvirt, getValue);
                if (parameterWrapper.Type.IsValueType)
                {
                    gen.Emit(OpCodes.Unbox_Any, parameterWrapper.Type);
                }
                else
                {
                    gen.Emit(OpCodes.Castclass, parameterWrapper.Type);
                }
                iii++;
            }
            gen.Emit(OpCodes.Callvirt, implementationMethod);
            gen.Emit(OpCodes.Stloc_2);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldc_I4, 200);
            gen.Emit(OpCodes.Ldloc_2);
            gen.Emit(OpCodes.Call, createResponse);
            gen.Emit(OpCodes.Stloc_3);
            gen.BeginCatchBlock(typeof(Exception));
            gen.Emit(OpCodes.Stloc_S, 4);
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloc_S, 4);
            gen.Emit(OpCodes.Call, method9);
            gen.Emit(OpCodes.Call, fromResult);
            gen.Emit(OpCodes.Stloc_3);
            gen.EndExceptionBlock();
            gen.Emit(OpCodes.Ldloc_3);
            gen.Emit(OpCodes.Ret);
            // finished
            return(method);
        }
Beispiel #4
0
        private MethodBuilder VoidMethodBuilder(MethodInfo implementationMethod, MethodBuilder method, Type[] pTypes, List <ParameterWrapper> methodParams)
        {
            MethodInfo gatherParams = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod(
                "GatherParameters",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(String),
                typeof(Object[])
            },
                null
                );
            var        baseType       = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType);
            var        implementation = baseType.GetRuntimeFields().Single(f => f.Name == "implementation");
            MethodInfo getValue       = typeof(ParameterWrapper).GetMethod(
                "get_value",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
            },
                null
                );
            MethodInfo createResponse = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod("CreateResponse", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (implementationMethod.ReturnType == typeof(void))
            {
                createResponse = createResponse.MakeGenericMethod(typeof(object));
            }
            else
            {
                createResponse = createResponse.MakeGenericMethod(implementationMethod.ReturnType);
            }
            MethodInfo method9 = typeof(ServiceWrapperBase <>).MakeGenericType(implementationMethod.DeclaringType).GetMethod(
                "CreateErrorResponse",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] {
                typeof(Exception)
            },
                null
                );
            ILGenerator gen = method.GetILGenerator();
            // Preparing locals
            LocalBuilder parameters        = gen.DeclareLocal(typeof(Object[]));
            LocalBuilder serviceParameters = gen.DeclareLocal(typeof(ParameterWrapper[]));
            LocalBuilder message           = gen.DeclareLocal(typeof(IActionResult));
            LocalBuilder ex = gen.DeclareLocal(typeof(Exception));

            // Writing body
            gen.Emit(OpCodes.Nop);
            gen.BeginExceptionBlock();
            gen.Emit(OpCodes.Nop);
            var ps = pTypes;

            EmitHelpers.EmitInt32(gen, ps.Length);
            gen.Emit(OpCodes.Newarr, typeof(object));
            for (int j = 0; j < ps.Length; j++)
            {
                gen.Emit(OpCodes.Dup);
                EmitHelpers.EmitInt32(gen, j);
                EmitHelpers.EmitLdarg(gen, j + 1);
                var paramType = ps[j];
                if (paramType.IsValueType)
                {
                    gen.Emit(OpCodes.Box, paramType);
                }
                gen.Emit(OpCodes.Stelem_Ref);
            }
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, implementationMethod.Name);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Call, gatherParams);
            gen.Emit(OpCodes.Stloc_1);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, implementation);
            int iii = 0;

            foreach (var parameterWrapper in methodParams)
            {
                gen.Emit(OpCodes.Ldloc_1);
                EmitHelpers.EmitInt32(gen, iii);//gen.Emit(OpCodes.Ldc_I4_0);
                gen.Emit(OpCodes.Ldelem_Ref);
                gen.Emit(OpCodes.Callvirt, getValue);
                if (parameterWrapper.Type.IsValueType)
                {
                    gen.Emit(OpCodes.Unbox_Any, parameterWrapper.Type);
                }
                else
                {
                    gen.Emit(OpCodes.Castclass, parameterWrapper.Type);
                }
                iii++;
            }
            gen.Emit(OpCodes.Callvirt, implementationMethod);
            if (implementationMethod.ReturnType != typeof(void))
            {
                gen.Emit(OpCodes.Stloc_2);
            }
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldc_I4, 200);
            if (implementationMethod.ReturnType != typeof(void))
            {
                gen.Emit(OpCodes.Ldloc_2);
            }
            else
            {
                gen.Emit(OpCodes.Ldnull);
            }

            gen.Emit(OpCodes.Call, createResponse);
            gen.Emit(OpCodes.Stloc_2);
            gen.BeginCatchBlock(typeof(Exception));
            gen.Emit(OpCodes.Stloc_3);
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloc_3);
            gen.Emit(OpCodes.Call, method9);
            gen.Emit(OpCodes.Stloc_2);
            gen.EndExceptionBlock();
            gen.Emit(OpCodes.Ldloc_2);
            gen.Emit(OpCodes.Ret);
            // finished
            return(method);
        }