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); }
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); }
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); }
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 Type CreateDelegate(MethodInfo targetMethod, TypeBuilder parent, List <ParameterWrapper> methodParams) { typeCounter++; var typeBuilder = myModuleBuilder.DefineType(string.Format("TempModule.Controllers.{0}{1}{2}Delegate{3}", targetMethod.DeclaringType.Name, targetMethod.Name, targetMethod.GetParameters().Length, typeCounter), TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(object)); //var typeBuilder = myModuleBuilder.DefineType(string.Format("{0}{1}{2}Delegate", targetMethod.DeclaringType.Name, targetMethod.Name, targetMethod.GetParameters().Length), TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(object)); var imp = typeBuilder.DefineField("implementation", parent, FieldAttributes.Public); var baseController = typeof(ServiceWrapperBase <>).MakeGenericType(targetMethod.DeclaringType).GetField("implementation", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var param = typeBuilder.DefineField("parameters", typeof(ParameterWrapper[]), FieldAttributes.Public); CreateDelegateCtor(typeBuilder); // Declaring method builder // Method attributes System.Reflection.MethodAttributes methodAttributes = System.Reflection.MethodAttributes.Assembly | System.Reflection.MethodAttributes.HideBySig; MethodBuilder method = typeBuilder.DefineMethod(targetMethod.Name, methodAttributes); // Preparing Reflection instances //FieldInfo field1 = typeof(<> c__DisplayClass2_0).GetField("<>4__this", BindingFlags.Public | BindingFlags.NonPublic); //FieldInfo field2 = typeof(Stardust.Interstellar.Rest.Service.ServiceWrapperBase<>).MakeGenericType(typeof(ITestApi)).GetField("implementation", BindingFlags.Public | BindingFlags.NonPublic); //FieldInfo field3 = typeof(<> c__DisplayClass2_0).GetField("serviceParameters", BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method4 = typeof(ParameterWrapper).GetMethod( "get_value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null ); MethodInfo method5 = targetMethod; // Setting return type method.SetReturnType(targetMethod.ReturnType); // Adding parameters ILGenerator gen = method.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, imp); gen.Emit(OpCodes.Ldfld, baseController); var iii = 0; foreach (var item in methodParams) { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, param); EmitHelpers.EmitInt32(gen, iii); gen.Emit(OpCodes.Ldelem_Ref); gen.Emit(OpCodes.Callvirt, method4); if (item.Type.IsValueType) { gen.Emit(OpCodes.Unbox_Any, item.Type); } else { gen.Emit(OpCodes.Castclass, item.Type); } iii++; } gen.Emit(OpCodes.Callvirt, method5); gen.Emit(OpCodes.Ret); // finished var t = typeBuilder.CreateType(); return(t); }