public MethodInformation ProcessMethod(MethodInfo method) { MappingAttribute mappingAttribute = null; GetAttribute getAttribute = null; IList <Type> args = method.GetParameters().Select(arg => arg.ParameterType).ToList(); foreach (var attr in method.GetCustomAttributes <Attribute>()) { switch (attr) { case MappingAttribute ma: mappingAttribute = ma; break; case GetAttribute ga: getAttribute = ga; break; } } var info = new MethodInformation { Name = method.Name, ReturnType = method.ReturnType, Args = args }; if (mappingAttribute != null) { info.Mapping = mappingAttribute; } if (getAttribute != null) { info.Get = getAttribute; } info.MethodAttrs = method.Attributes; return(info); }
public void EmitMethod(TypeBuilder typeBuilder, MethodInformation methodInfo) { var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.ReuseSlot, methodInfo.ReturnType, methodInfo.Args.ToArray()); var ilGen = methodBuilder.GetILGenerator(); ilGen.DeclareLocal(typeof(string)); ilGen.Emit(OpCodes.Ldstr, methodInfo.Get.path); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, typeof(Base).GetField("req")); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Ldc_I4, methodInfo.Args.Count); ilGen.Emit(OpCodes.Newarr, typeof(string)); ilGen.Emit(OpCodes.Dup); var argsCount = methodInfo.Args.Count; for (var i = 0; i < argsCount; i++) { ilGen.Emit(OpCodes.Ldc_I4, i); var index = i + 1; if (methodInfo.Args[i].IsValueType) //INT { ilGen.Emit(OpCodes.Ldarga_S, index); ilGen.Emit(OpCodes.Call, typeof(int).GetMethod("ToString", Type.EmptyTypes)); } else //STRING { ilGen.Emit(OpCodes.Ldarg, index); ilGen.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString", Type.EmptyTypes)); } ilGen.Emit(OpCodes.Stelem_Ref); if (i != argsCount - 1 && argsCount > 1) { ilGen.Emit(OpCodes.Dup); } } ilGen.Emit(OpCodes.Call, typeof(Base).GetRuntimeMethods().ElementAt(0)); ilGen.Emit(OpCodes.Ldtoken, methodInfo.Mapping.Dto); ilGen.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static) ?? throw new Exception()); ilGen.Emit(OpCodes.Callvirt, typeof(IRequest).GetMethod("Get")); GenResult(ilGen, methodInfo.Mapping); ilGen.Emit(OpCodes.Ret); }