/// <summary>
        /// Register gear app
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configAction"></param>
        /// <returns></returns>
        public static IServiceProvider RegisterGearWebApp(this IServiceCollection services, Action <GearServiceCollectionConfig> configAction)
        {
            var configuration = new GearServiceCollectionConfig
            {
                GearServices = services
            };

            configAction(configuration);

            //Register system config
            services.RegisterSystemConfig(configuration.Configuration);

            services.Configure <FormOptions>(x => x.ValueCountLimit =
                                                 configuration.ServerConfiguration.UploadMaximSize);

            //Global settings
            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
                options.ModelBinderProviders.Insert(0, new GearDictionaryModelBinderProvider());
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(x =>
            {
                x.SerializerSettings.DateFormatString = GearSettings.Date.DateFormat;
            });

            services.AddGearSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddGearSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.AddUrlHelper();

            //Register core razor
            services.RegisterCoreRazorModule();

            //Use compression
            if (configuration.AddResponseCompression && configuration.HostingEnvironment.IsProduction())
            {
                services.AddResponseCompression();
            }

            services.AddHttpClient();

            services.Configure <SecurityStampValidatorOptions>(options =>
            {
                // enables immediate logout, after updating the user's stat.
                options.ValidationInterval = TimeSpan.Zero;
            });

            //--------------------------------------Cors origin Module-------------------------------------
            if (configuration.UseDefaultCorsConfiguration)
            {
                services.AddOriginCorsModule();
            }

            //---------------------------------Custom cache Module-------------------------------------
            if (configuration.CacheConfiguration.UseDistributedCache &&
                configuration.CacheConfiguration.UseInMemoryCache)
            {
                throw new InvalidCacheConfigurationException("Both types of cached storage cannot be used");
            }

            if (configuration.CacheConfiguration.UseDistributedCache)
            {
                services.AddDistributedMemoryCache()
                .AddCacheModule <DistributedCacheService, RedisConnection>(configuration.HostingEnvironment, configuration.Configuration);
            }
            else if (configuration.CacheConfiguration.UseInMemoryCache)
            {
                services.AddCacheModule <InMemoryCacheService, RedisConnection>(configuration.HostingEnvironment, configuration.Configuration);
            }

            //---------------------------------Api version Module-------------------------------------
            services.AddApiVersioning(options =>
            {
                options.ReportApiVersions = configuration.ApiVersioningOptions.ReportApiVersions;
                options.AssumeDefaultVersionWhenUnspecified = configuration.ApiVersioningOptions.AssumeDefaultVersionWhenUnspecified;
                options.DefaultApiVersion = configuration.ApiVersioningOptions.DefaultApiVersion;
                options.ErrorResponses    = configuration.ApiVersioningOptions.ErrorResponses;
            });

            //--------------------------------------SignalR Module-------------------------------------
            if (configuration.SignlarConfiguration.UseDefaultConfiguration)
            {
                services.AddSignalRModule();
            }


            //--------------------------------------Swagger Module-------------------------------------
            if (configuration.SwaggerServicesConfiguration.UseDefaultConfiguration)
            {
                services.AddSwaggerModule(configuration.Configuration);
            }

            //Register memory cache
            var cacheService = configuration.BuildGearServices.GetService <IMemoryCache>();

            IoC.Container.Register(Component.For <IMemoryCache>().Instance(cacheService));

            return(WindsorRegistrationHelper.CreateServiceProvider(IoC.Container, services));
        }
        /// <summary>
        /// Register gear app
        /// </summary>
        /// <param name="services"></param>
        /// <param name="hostingEnvironment"></param>
        /// <param name="configAction"></param>
        /// <param name="conf"></param>
        /// <returns></returns>
        public static IServiceProvider RegisterGearWebApp(this IServiceCollection services, IConfiguration conf, IHostingEnvironment hostingEnvironment, Action <GearServiceCollectionConfig> configAction)
        {
            IoC.Container.Register(Component.For <IConfiguration>().Instance(conf));
            IoC.Container.Register(Component.For <IHostingEnvironment>().Instance(hostingEnvironment));

            //----------------------------------------Health Check-------------------------------------
            services.AddHealthChecks();
            services.AddDatabaseHealth();
            //services.AddSeqHealth();
            services.AddHealthChecksUI("health-gear-database", setup =>
            {
                setup.SetEvaluationTimeInSeconds((int)TimeSpan.FromMinutes(2).TotalSeconds);
                setup.AddHealthCheckEndpoint(GearApplication.SystemConfig.MachineIdentifier, $"{GearApplication.SystemConfig.EntryUri}hc");
            });



            var configuration = new GearServiceCollectionConfig
            {
                GearServices       = services,
                HostingEnvironment = hostingEnvironment,
                Configuration      = conf
            };

            configAction(configuration);

            //Register mappings from modules
            services.AddAutoMapper(configuration.GetAutoMapperProfilesFromAllAssemblies().ToArray());

            //Register system config
            services.RegisterSystemConfig(configuration.Configuration);

            services.Configure <FormOptions>(x => x.ValueCountLimit =
                                                 configuration.ServerConfiguration.UploadMaximSize);

            //Global settings
            services.AddMvc(options =>
            {
                //Global
                options.EnableEndpointRouting = false;

                //Binders
                options.ModelBinderProviders.Insert(0, new GearDictionaryModelBinderProvider());
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(x =>
            {
                x.SerializerSettings.DateFormatString = GearSettings.Date.DateFormat;
            });
            services.AddGearSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddGearSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.AddUrlHelper();

            //Use compression
            if (configuration.AddResponseCompression && configuration.HostingEnvironment.IsProduction())
            {
                services.AddResponseCompression();
            }

            services.AddHttpClient();

            services.Configure <SecurityStampValidatorOptions>(options =>
            {
                // enables immediate logout, after updating the user's stat.
                options.ValidationInterval = TimeSpan.Zero;
            });

            //--------------------------------------Cors origin Module-------------------------------------
            if (configuration.UseDefaultCorsConfiguration)
            {
                services.AddOriginCorsModule();
            }

            //---------------------------------Custom cache Module-------------------------------------
            if (configuration.CacheConfiguration.UseDistributedCache &&
                configuration.CacheConfiguration.UseInMemoryCache)
            {
                throw new InvalidCacheConfigurationException("Both types of cached storage cannot be used");
            }

            if (configuration.CacheConfiguration.UseDistributedCache)
            {
                services.AddDistributedMemoryCache()
                .AddCacheModule <DistributedCacheService>()
                .AddRedisCacheConfiguration <RedisConnection>(configuration.HostingEnvironment, configuration.Configuration);
            }
            else if (configuration.CacheConfiguration.UseInMemoryCache)
            {
                services.AddCacheModule <InMemoryCacheService>();
            }

            //---------------------------------Api version Module-------------------------------------
            services.AddApiVersioning(options =>
            {
                options.ReportApiVersions = configuration.ApiVersioningOptions.ReportApiVersions;
                options.AssumeDefaultVersionWhenUnspecified = configuration.ApiVersioningOptions.AssumeDefaultVersionWhenUnspecified;
                options.DefaultApiVersion = configuration.ApiVersioningOptions.DefaultApiVersion;
                options.ErrorResponses    = configuration.ApiVersioningOptions.ErrorResponses;
            });

            //--------------------------------------Swagger Module-------------------------------------
            if (configuration.SwaggerServicesConfiguration.UseDefaultConfiguration)
            {
                services.AddSwaggerModule(configuration.Configuration);
            }

            //Register memory cache
            IoC.Container.Register(Component
                                   .For <IMemoryCache>()
                                   .Instance(configuration.BuildGearServices.GetService <IMemoryCache>()));


            //Type Convertors
            TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(EuDateTimeConvertor)));

            return(WindsorRegistrationHelper.CreateServiceProvider(IoC.Container, services));
        }