Example #1
0
        private static ControllerCompilation Compile <T>(ServiceDef servicedef)
        {
            if (!compiledtypes.TryGetValue(typeof(T), out ControllerCompilation wrapper))
            {
                Type t = typeof(T);

                var           assemblyname    = new AssemblyName(Guid.NewGuid().ToString());
                var           assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyname, AssemblyBuilderAccess.Run);
                ModuleBuilder moduleBuilder   = assemblyBuilder.DefineDynamicModule("MainModule");

                TypeBuilder typeBuilder = moduleBuilder.DefineType($"{t.FullName}Controller"
                                                                   , TypeAttributes.Public |
                                                                   TypeAttributes.Class |
                                                                   TypeAttributes.AutoClass |
                                                                   TypeAttributes.AnsiClass |
                                                                   TypeAttributes.BeforeFieldInit |
                                                                   TypeAttributes.AutoLayout
                                                                   , typeof(ControllerBase));

                foreach (var a in t.GetCustomAttributes(true))
                {
                    if (a is RouteAttribute)
                    {
                        var ca = new CustomAttributeBuilder(a.GetType().GetConstructor(new Type[] { typeof(string) }), new object[] { (a as RouteAttribute).Template });
                        typeBuilder.SetCustomAttribute(ca);
                    }
                }
                var _services = typeBuilder.DefineField("_services", typeof(ISimpleServicesFactory), FieldAttributes.Private);

                {
                    ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(ISimpleServicesFactory) });

                    var il = cb.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, typeof(ControllerBase).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null));
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Stfld, _services);
                    il.Emit(OpCodes.Ret);
                }
                var mm = servicedef.Methods;

                for (int nit = 0; nit < mm.Length; nit++)
                {
                    var m = mm[nit].MethodInfo;
                    //    var pp = m.GetParameters();

                    var mb = typeBuilder.DefineMethod(m.Name, MethodAttributes.Public /*| MethodAttributes.Virtual*/, typeof(IActionResult), new Type[0] /* pp.Select(_p => _p.ParameterType).ToArray() */);
                    var il = mb.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, _services);

                    il.Emit(OpCodes.Ldarg_0);

                    var mi  = typeof(ISimpleServicesFactory).GetMethods().Single(_m => _m.Name == "CheckRequest" && _m.GetGenericArguments().Length == 1);
                    var mi2 = mi.MakeGenericMethod(typeof(T));

                    il.Emit(OpCodes.Callvirt, mi2);

                    //      il.Emit(OpCodes.Ldstr, "info");
                    //       il.Emit(OpCodes.Newobj, typeof(OkObjectResult).GetConstructor(new Type[] { typeof(object) }));

                    //     il.Emit(OpCodes.Stloc_0);
                    //      il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ret);
                }

                var info = typeBuilder.CreateTypeInfo();
                var type = info.AsType();
                wrapper = new ControllerCompilation()
                {
                    Type    = type,
                    Methods = mm
                };
                compiledtypes[typeof(T)] = wrapper;
            }
            return(wrapper);
        }
Example #2
0
        private static ControllerCompilation Compile2(ServiceDef servicedef, Type t) // PROTO4
        {
            if (!compiledtypes.TryGetValue(t, out ControllerCompilation wrapper))
            {
                var           assemblyname    = new AssemblyName(Guid.NewGuid().ToString());
                var           assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyname, AssemblyBuilderAccess.Run);
                ModuleBuilder moduleBuilder   = assemblyBuilder.DefineDynamicModule("MainModule");

                TypeBuilder typeBuilder = moduleBuilder.DefineType($"{t.FullName}Controller"
                                                                   , TypeAttributes.Public |
                                                                   TypeAttributes.Class |
                                                                   TypeAttributes.AutoClass |
                                                                   TypeAttributes.AnsiClass |
                                                                   TypeAttributes.BeforeFieldInit |
                                                                   TypeAttributes.AutoLayout
                                                                   , typeof(Internals.ServiceControllerBase));

                foreach (var a in t.GetCustomAttributes(true))
                {
                    if (a is RouteAttribute)
                    {
                        var ca = new CustomAttributeBuilder(a.GetType().GetConstructor(new Type[] { typeof(string) }), new object[] { (a as RouteAttribute).Template });
                        typeBuilder.SetCustomAttribute(ca);
                    }
                    if (a is AuthorizeAttribute)
                    {
                        var aa = a as AuthorizeAttribute;
                        var ca = new CustomAttributeBuilder(a.GetType().GetConstructor(new Type[0]), new object[0],
                                                            new PropertyInfo[] { a.GetType().GetProperty("Policy"), a.GetType().GetProperty("Roles"), a.GetType().GetProperty("AuthenticationSchemes") },
                                                            new object[] { aa.Policy, aa.Roles, aa.AuthenticationSchemes });
                        typeBuilder.SetCustomAttribute(ca);
                    }
                    if (a is AllowAnonymousAttribute)
                    {
                        var aa = a as AllowAnonymousAttribute;
                        var ca = new CustomAttributeBuilder(a.GetType().GetConstructor(new Type[0]), new object[0]);
                        typeBuilder.SetCustomAttribute(ca);
                    }
                }

                var oc = t.GetConstructors().SingleOrDefault();
                var pp = oc.GetParameters();


                //     var _services = typeBuilder.DefineField("_services", typeof(ISimpleServicesFactory), FieldAttributes.Private);
                var _controller = typeBuilder.DefineField("_controller", t, FieldAttributes.Private);


                {
                    var _methods = typeof(Internals.ServiceControllerBase).GetField("_methods", BindingFlags.NonPublic | BindingFlags.Instance);

                    ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.Standard, pp.Select(_p => _p.ParameterType).ToArray());
                    var il = cb.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, typeof(Internals.ServiceControllerBase).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null));

                    il.Emit(OpCodes.Ldarg_0);
                    for (int nit = 0; nit < pp.Length; nit++)
                    {
                        LdArg(il, nit + 1);
                    }
                    il.Emit(OpCodes.Newobj, t.GetConstructors().Single());
                    il.Emit(OpCodes.Stfld, _controller);

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldtoken, t);
                    il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static));
                    il.Emit(OpCodes.Call, typeof(SimpleServicesFactory).GetMethod("GetMethods", new Type[] { typeof(Type) }));
                    il.Emit(OpCodes.Stfld, _methods);

                    il.Emit(OpCodes.Ret);
                }
                //       ConstructorBuilder cb2 = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.Standard, new Type[0]);
                //      var ils = cb2.GetILGenerator();

                var mm   = SimpleServicesFactory.GetMethods(t);
                var done = Enumerable.Repeat(false, mm.Length).ToArray();

                for (int nit = 0; nit < mm.Length; nit++)
                {
                    if (!done[nit])
                    {
                        var themethods = mm.Skip(nit).Where(_m => mm[nit].Contract.Name == _m.Contract.Name).OrderBy(_m => _m.Order).ToArray();

                        var getm  = themethods.Where(_m => _m.Get).ToArray();
                        var postm = themethods.Where(_m => _m.Post).ToArray();

                        if (getm.Length > 1 || postm.Length > 1)
                        {
                            throw new AmbiguousMatchException();
                        }
                        if (getm.FirstOrDefault() == postm.FirstOrDefault())
                        {
                            var ind = Array.IndexOf(mm, getm.First());
                            MakeMethod(typeBuilder, null, mm, ind, _controller);
                        }
                        else
                        {
                            if (getm.Any())
                            {
                                var ind = Array.IndexOf(mm, getm.First());
                                MakeMethod(typeBuilder, "GET", mm, ind, _controller);
                            }
                            if (postm.Any())
                            {
                                var ind = Array.IndexOf(mm, postm.First());
                                MakeMethod(typeBuilder, "POST", mm, ind, _controller);
                            }
                        }

                        string url;// = m.MethodInfo.GetCustomAttributes<HttpMethodAttribute>().FirstOrDefault()?.Template;

                        //  if ((url?.Length ?? 0) == 0)
                        {
                            url = mm[nit].Contract.Name;
                        }

                        /*      var n = "_static" + mm[nit].Contract.Name;
                         *    var _static = typeBuilder.DefineField(n, typeof(int[]), FieldAttributes.Static|FieldAttributes.Private);
                         *
                         *    Ldc_i4_x(ils, themethods.Length);
                         *    ils.Emit(OpCodes.Newarr, typeof(int));
                         *    ils.Emit(OpCodes.Stsfld, _static);
                         *
                         *    for (int g = 0; g < themethods.Count(); g++)
                         *    {
                         *        var ind = Array.IndexOf(mm, themethods.Skip(g).First());
                         *
                         *        ils.Emit(OpCodes.Ldsfld, _static);
                         *        Ldc_i4_x(ils, g);
                         *        Ldc_i4_x(ils, ind);
                         *        ils.Emit(OpCodes.Stelem_I4);
                         *        done[ind] = true;
                         *    }*/
                    }
                }
                //  ils.Emit(OpCodes.Ret);

                var info = typeBuilder.CreateTypeInfo();
                var type = info.AsType();
                wrapper = new ControllerCompilation()
                {
                    Type    = type,
                    Methods = servicedef.Methods
                };
                compiledtypes[t] = wrapper;
            }
            return(wrapper);
        }