Ejemplo n.º 1
0
 public SimpleServicesHandlerMiddleware(ISimpleServicesFactory owner, IServiceProvider services)
 {
     this.owner    = owner as SimpleServicesFactory;
     this.services = services;
 }
Ejemplo n.º 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);
        }