예제 #1
0
        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);
        }
예제 #2
0
        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);
        }