public static IServiceCollection AddFrameworkService(this IServiceCollection services,
                                                             Func <ActionExecutingContext, string> CsSector = null,
                                                             List <IDataPrivilege> dataPrivilegeSettings    = null,
                                                             WebHostBuilderContext webHostBuilderContext    = null
                                                             )
        {
            CurrentDirectoryHelpers.SetCurrentDirectory();

            var configBuilder = new ConfigurationBuilder();

            if (!File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json")))
            {
                var binLocation = Assembly.GetEntryAssembly()?.Location;
                if (!string.IsNullOrEmpty(binLocation))
                {
                    var binPath = new FileInfo(binLocation).Directory?.FullName;
                    if (File.Exists(Path.Combine(binPath, "appsettings.json")))
                    {
                        Directory.SetCurrentDirectory(binPath);
                        configBuilder.SetBasePath(binPath)
                        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddEnvironmentVariables();
                    }
                }
            }
            else
            {
                configBuilder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
            }

            if (webHostBuilderContext != null)
            {
                var env = webHostBuilderContext.HostingEnvironment;
                configBuilder
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
            }
            var config = configBuilder.Build();

            services.AddLocalization(options => options.ResourcesPath = "Resources");
            var gd  = GetGlobalData();
            var con = config.Get <Configs>() ?? new Configs();

            //services.Configure<Configs>(config);
            if (dataPrivilegeSettings != null)
            {
                con.DataPrivilegeSettings = dataPrivilegeSettings;
            }
            else
            {
                con.DataPrivilegeSettings = new List <IDataPrivilege>();
            }
            SetDbContextCI(gd.AllAssembly, con);
            gd.AllModels = GetAllModels(con);
            services.AddSingleton(gd);
            services.AddSingleton(con);
            services.AddResponseCaching();
            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.Cookie.Name = con.CookiePre + ".Session";
                options.IdleTimeout = TimeSpan.FromSeconds(3600);
            });
            SetupDFS(con);

            services.AddCors(options =>
            {
                if (con.CorsOptions?.Policy?.Count > 0)
                {
                    foreach (var item in con.CorsOptions.Policy)
                    {
                        string[] domains = item.Domain?.Split(',');
                        options.AddPolicy(item.Name,
                                          builder =>
                        {
                            builder.WithOrigins(domains)
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .AllowCredentials();
                        });
                    }
                }
                else
                {
                    options.AddPolicy("_donotusedefault",
                                      builder =>
                    {
                        builder.WithOrigins("http://localhost",
                                            "https://localhost")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                    });
                }
            });


            // edit start by @vito
            services.TryAdd(ServiceDescriptor.Transient <IAuthorizationService, WTMAuthorizationService>());
            services.TryAdd(ServiceDescriptor.Transient <IPolicyEvaluator, Core.Auth.PolicyEvaluator>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IApplicationModelProvider, Core.Auth.AuthorizationApplicationModelProvider>());
            // edit end

            var mvc   = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.dll").FirstOrDefault();
            var admin = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.Admin.dll").FirstOrDefault();

            //set Core's _Callerlocalizer to use localizer point to the EntryAssembly's Program class
            var programType      = Assembly.GetEntryAssembly().GetTypes().Where(x => x.Name == "Program").FirstOrDefault();
            var coredll          = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Core.dll").FirstOrDefault();
            var programLocalizer = new ResourceManagerStringLocalizerFactory(
                Options.Create(
                    new LocalizationOptions
            {
                ResourcesPath = "Resources"
            })
                , new Microsoft.Extensions.Logging.LoggerFactory()
                )
                                   .Create(programType);

            coredll.GetType("WalkingTec.Mvvm.Core.Program").GetProperty("_Callerlocalizer").SetValue(null, programLocalizer);


            services.AddMvc(options =>
            {
                // ModelBinderProviders
                options.ModelBinderProviders.Insert(0, new StringBinderProvider());

                // Filters
                options.Filters.Add(new AuthorizeFilter());
                options.Filters.Add(new DataContextFilter(CsSector));
                options.Filters.Add(new PrivilegeFilter());
                options.Filters.Add(new FrameworkFilter());
            })
            .AddJsonOptions(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // custom ContractResolver
                options.SerializerSettings.ContractResolver = new WTMContractResolver()
                {
                    //NamingStrategy = new CamelCaseNamingStrategy()
                };
            })
            .ConfigureApplicationPartManager(m =>
            {
                var feature = new ControllerFeature();
                if (mvc != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(mvc));
                }
                if (admin != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(admin));
                }
                m.PopulateFeature(feature);
                services.AddSingleton(feature.Controllers.Select(t => t.AsType()).ToArray());
            })
            .AddControllersAsServices()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressModelStateInvalidFilter  = true;
                options.InvalidModelStateResponseFactory = (a) =>
                {
                    return(new BadRequestObjectResult(a.ModelState.GetErrorJson()));
                };
            })
            .AddDataAnnotationsLocalization(options =>
            {
                var coreType = coredll?.GetTypes().Where(x => x.Name == "Program").FirstOrDefault();
                options.DataAnnotationLocalizerProvider = (type, factory) =>
                {
                    if (Core.Program.Buildindll.Any(x => type.FullName.StartsWith(x)))
                    {
                        var rv = factory.Create(coreType);
                        return(rv);
                    }
                    else
                    {
                        return(factory.Create(programType));
                    }
                };
            })
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);


            services.Configure <RazorViewEngineOptions>(options =>
            {
                if (mvc != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            mvc,
                            "WalkingTec.Mvvm.Mvc" // your external assembly's base namespace
                            )
                        );
                }
                if (admin != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            admin,
                            "WalkingTec.Mvvm.Mvc.Admin" // your external assembly's base namespace
                            )
                        );
                }
            });

            services.Configure <FormOptions>(y =>
            {
                y.ValueLengthLimit         = int.MaxValue;
                y.MultipartBodyLengthLimit = con.FileUploadOptions.UploadLimit;
            });

            services.AddSingleton <IUIService, DefaultUIService>();

            #region CookieWithJwtAuth

            // services.AddSingleton<UserStore>();
            services.AddSingleton <ITokenService, TokenService>();

            var jwtOptions = config.GetSection("JwtOptions").Get <JwtOptions>();
            if (jwtOptions == null)
            {
                jwtOptions = new JwtOptions();
            }
            services.Configure <JwtOptions>(config.GetSection("JwtOptions"));

            var cookieOptions = config.GetSection("CookieOptions").Get <Core.Auth.CookieOptions>();
            if (cookieOptions == null)
            {
                cookieOptions = new Core.Auth.CookieOptions();
            }

            services.Configure <Core.Auth.CookieOptions>(config.GetSection("CookieOptions"));

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.Cookie.Name     = CookieAuthenticationDefaults.CookiePrefix + AuthConstants.CookieAuthName;
                options.Cookie.HttpOnly = true;
                options.Cookie.SameSite = SameSiteMode.Strict;

                options.ClaimsIssuer      = cookieOptions.Issuer;
                options.SlidingExpiration = cookieOptions.SlidingExpiration;
                options.ExpireTimeSpan    = TimeSpan.FromSeconds(cookieOptions.Expires);
                // options.SessionStore = new MemoryTicketStore();

                options.LoginPath          = cookieOptions.LoginPath;
                options.LogoutPath         = cookieOptions.LogoutPath;
                options.ReturnUrlParameter = cookieOptions.ReturnUrlParameter;
                options.AccessDeniedPath   = cookieOptions.AccessDeniedPath;
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = AuthConstants.JwtClaimTypes.Name,
                    RoleClaimType = AuthConstants.JwtClaimTypes.Role,

                    ValidateIssuer = true,
                    ValidIssuer    = jwtOptions.Issuer,

                    ValidateAudience = true,
                    ValidAudience    = jwtOptions.Audience,

                    ValidateIssuerSigningKey = false,
                    IssuerSigningKey         = jwtOptions.SymmetricSecurityKey,

                    ValidateLifetime = true
                };
            });
            #endregion

            GlobalServices.SetServiceProvider(services.BuildServiceProvider());
            return(services);
        }
        public static IServiceCollection AddFrameworkService(this IServiceCollection services,
                                                             Func <ActionExecutingContext, string> CsSector = null,
                                                             List <IDataPrivilege> dataPrivilegeSettings    = null,
                                                             WebHostBuilderContext webHostBuilderContext    = null
                                                             )
        {
            CurrentDirectoryHelpers.SetCurrentDirectory();

            var configBuilder = new ConfigurationBuilder();

            if (!File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json")))
            {
                var binLocation = Assembly.GetEntryAssembly()?.Location;
                if (!string.IsNullOrEmpty(binLocation))
                {
                    var binPath = new FileInfo(binLocation).Directory?.FullName;
                    if (File.Exists(Path.Combine(binPath, "appsettings.json")))
                    {
                        Directory.SetCurrentDirectory(binPath);
                        configBuilder.SetBasePath(binPath)
                        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddEnvironmentVariables();
                    }
                }
            }
            else
            {
                configBuilder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
            }

            if (webHostBuilderContext != null)
            {
                var env = webHostBuilderContext.HostingEnvironment;
                configBuilder
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
            }
            var config = configBuilder.Build();

            var gd = GetGlobalData();

            services.AddSingleton(gd);
            var con = config.Get <Configs>() ?? new Configs();

            if (dataPrivilegeSettings != null)
            {
                con.DataPrivilegeSettings = dataPrivilegeSettings;
            }
            else
            {
                con.DataPrivilegeSettings = new List <IDataPrivilege>();
            }
            services.AddSingleton(con);
            services.AddResponseCaching();
            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.Cookie.Name = con.CookiePre + ".Session";
                options.IdleTimeout = TimeSpan.FromSeconds(3600);
            });
            SetupDFS(con);

            services.AddCors(options =>
            {
                if (con.CorsOptions?.Policy?.Count > 0)
                {
                    foreach (var item in con.CorsOptions.Policy)
                    {
                        string[] domains = item.Domain?.Split(',');
                        options.AddPolicy(item.Name,
                                          builder =>
                        {
                            builder.WithOrigins(domains)
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .AllowCredentials();
                        });
                    }
                }
                else
                {
                    options.AddPolicy("_donotusedefault",
                                      builder =>
                    {
                        builder.WithOrigins("http://localhost",
                                            "https://localhost")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                    });
                }
            });



            var mvc   = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.dll").FirstOrDefault();
            var admin = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.Admin.dll").FirstOrDefault();

            services.AddMvc(options =>
            {
                // ModelBinderProviders
                options.ModelBinderProviders.Insert(0, new StringBinderProvider());

                // Filters
                options.Filters.Add(new DataContextFilter(CsSector));
                options.Filters.Add(new PrivilegeFilter());
                options.Filters.Add(new FrameworkFilter());
            })
            .AddJsonOptions(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // custom ContractResolver
                options.SerializerSettings.ContractResolver = new WTMContractResolver()
                {
                    //NamingStrategy = new CamelCaseNamingStrategy()
                };
            })
            .ConfigureApplicationPartManager(m =>
            {
                var feature = new ControllerFeature();
                if (mvc != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(mvc));
                }
                if (admin != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(admin));
                }
                m.PopulateFeature(feature);
                services.AddSingleton(feature.Controllers.Select(t => t.AsType()).ToArray());
            })
            .AddControllersAsServices()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressModelStateInvalidFilter  = true;
                options.InvalidModelStateResponseFactory = (a) =>
                {
                    return(new BadRequestObjectResult(a.ModelState.GetErrorJson()));
                };
            });


            services.Configure <RazorViewEngineOptions>(options =>
            {
                if (mvc != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            mvc,
                            "WalkingTec.Mvvm.Mvc" // your external assembly's base namespace
                            )
                        );
                }
                if (admin != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            admin,
                            "WalkingTec.Mvvm.Mvc.Admin" // your external assembly's base namespace
                            )
                        );
                }
            });

            services.Configure <FormOptions>(y =>
            {
                y.ValueLengthLimit         = int.MaxValue;
                y.MultipartBodyLengthLimit = con.FileUploadOptions.UploadLimit;
            });

            services.AddSingleton <IUIService, DefaultUIService>();
            GlobalServices.SetServiceProvider(services.BuildServiceProvider());
            return(services);
        }
        public static IServiceCollection AddFrameworkService(this IServiceCollection services,
            Func<ActionExecutingContext, string> CsSector = null,
            List<IDataPrivilege> dataPrivilegeSettings = null,
            WebHostBuilderContext webHostBuilderContext = null
        )
        {
            CurrentDirectoryHelpers.SetCurrentDirectory();
            IConfigurationRoot config = null;

            var configBuilder =
                    new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

            if (webHostBuilderContext != null)
            {
                IHostingEnvironment env = webHostBuilderContext.HostingEnvironment;
                configBuilder
                    .AddJsonFile(
                        $"appsettings.{env.EnvironmentName}.json",
                        optional: true,
                        reloadOnChange: true
                    );
            }
            config = configBuilder.Build();

            var gd = GetGlobalData();
            services.AddSingleton(gd);
            var con = config.Get<Configs>() ?? new Configs();
            if (dataPrivilegeSettings != null)
            {
                con.DataPrivilegeSettings = dataPrivilegeSettings;
            }
            else
            {
                con.DataPrivilegeSettings = new List<IDataPrivilege>();
            }
            services.AddSingleton(con);
            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.Cookie.Name = con.CookiePre + ".Session";
                options.IdleTimeout = TimeSpan.FromSeconds(3600);
            });
            SetupDFS(con);
            services.AddMvc(options =>
            {
                // ModelBinderProviders
                options.ModelBinderProviders.Insert(0, new StringBinderProvider());

                // Filters
                options.Filters.Add(new DataContextFilter(CsSector));
                options.Filters.Add(new PrivilegeFilter());
                options.Filters.Add(new FrameworkFilter());
            })
            .AddJsonOptions(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // custom ContractResolver
                options.SerializerSettings.ContractResolver = new WTMContractResolver()
                {
                    //NamingStrategy = new CamelCaseNamingStrategy()
                };
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);


            services.Configure<RazorViewEngineOptions>(options =>
            {
                options.FileProviders.Add(
                    new EmbeddedFileProvider(
                        typeof(_CodeGenController).GetTypeInfo().Assembly,
                        "WalkingTec.Mvvm.Mvc" // your external assembly's base namespace
                    )
                );
                var admin = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.Admin.dll").FirstOrDefault();
                if (admin != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            admin,
                            "WalkingTec.Mvvm.Mvc.Admin" // your external assembly's base namespace
                        )
                    );
                }
            });

            services.Configure<FormOptions>(y =>
            {
                y.ValueLengthLimit = int.MaxValue;
                y.MultipartBodyLengthLimit = con.FileUploadOptions.UploadLimit;
            });

            services.AddSingleton<IUIService, DefaultUIService>();
            GlobalServices.SetServiceProvider(services.BuildServiceProvider());
            return services;
        }
        public static IServiceCollection AddFrameworkService(this IServiceCollection services,
                                                             Func <ActionExecutingContext, string> CsSector = null,
                                                             List <IDataPrivilege> dataPrivilegeSettings    = null,
                                                             WebHostBuilderContext webHostBuilderContext    = null
                                                             )
        {
            CurrentDirectoryHelpers.SetCurrentDirectory();
            IConfigurationRoot config = null;

            var configBuilder =
                new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();

            if (webHostBuilderContext != null)
            {
                IHostingEnvironment env = webHostBuilderContext.HostingEnvironment;
                configBuilder
                .AddJsonFile(
                    $"appsettings.{env.EnvironmentName}.json",
                    optional: true,
                    reloadOnChange: true
                    );
            }
            config = configBuilder.Build();

            var gd = GetGlobalData();

            services.AddSingleton(gd);
            var con = config.Get <Configs>() ?? new Configs();

            AppSeetingConfig.AppSettings = con.AppSettings;
            if (dataPrivilegeSettings != null)
            {
                con.DataPrivilegeSettings = dataPrivilegeSettings;
            }
            else
            {
                con.DataPrivilegeSettings = new List <IDataPrivilege>();
            }
            services.AddSingleton(con);
            services.AddResponseCaching();
            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.Cookie.Name = con.CookiePre + ".Session";
                options.IdleTimeout = TimeSpan.FromSeconds(3600);
            });
            SetupDFS(con);


            var mvc   = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.dll").FirstOrDefault();
            var admin = gd.AllAssembly.Where(x => x.ManifestModule.Name == "WalkingTec.Mvvm.Mvc.Admin.dll").FirstOrDefault();

            services.AddMvc(options =>
            {
                // ModelBinderProviders
                options.ModelBinderProviders.Insert(0, new StringBinderProvider());

                // Filters
                options.Filters.Add(new DataContextFilter(CsSector));
                options.Filters.Add(new PrivilegeFilter());
                options.Filters.Add(new FrameworkFilter());
            })
            .AddJsonOptions(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // custom ContractResolver
                options.SerializerSettings.ContractResolver = new WTMContractResolver()
                {
                    //NamingStrategy = new CamelCaseNamingStrategy()
                };
            })
            .ConfigureApplicationPartManager(m =>
            {
                var feature = new ControllerFeature();
                if (mvc != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(mvc));
                }
                if (admin != null)
                {
                    m.ApplicationParts.Add(new AssemblyPart(admin));
                }
                m.PopulateFeature(feature);
                services.AddSingleton(feature.Controllers.Select(t => t.AsType()).ToArray());
            })
            .AddControllersAsServices()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressModelStateInvalidFilter  = true;
                options.InvalidModelStateResponseFactory = (a) =>
                {
                    return(new BadRequestObjectResult(a.ModelState.GetErrorJson()));
                };
            });


            services.Configure <RazorViewEngineOptions>(options =>
            {
                if (mvc != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            mvc,
                            "WalkingTec.Mvvm.Mvc" // your external assembly's base namespace
                            )
                        );
                }
                if (admin != null)
                {
                    options.FileProviders.Add(
                        new EmbeddedFileProvider(
                            admin,
                            "WalkingTec.Mvvm.Mvc.Admin" // your external assembly's base namespace
                            )
                        );
                }
            });

            services.Configure <FormOptions>(y =>
            {
                y.ValueLengthLimit         = int.MaxValue;
                y.MultipartBodyLengthLimit = con.FileUploadOptions.UploadLimit;
                y.MemoryBufferThreshold    = con.FileUploadOptions.UploadLimit;
            });

            services.AddSingleton <IUIService, DefaultUIService>();
            GlobalServices.SetServiceProvider(services.BuildServiceProvider());
            return(services);
        }