public static IServiceCollection AddAppDbContext(this IServiceCollection services, ISecretsManager secretsManager) { string connStr = secretsManager.Get(DataConsts.ConnStrKey); if (connStr is null) { throw new ArgumentNullException(nameof(connStr)); } services.AddNullConnectionPoolManager() .AddDbContext <DataContext>(options => options .UseSqlServer(connStr) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)); return(services); }
public static IServiceCollection AddAppDbContext(this IServiceCollection services, ISecretsManager secretsManager) { string connStr = secretsManager.Get(DataConsts.ConnStrKey); if (connStr is null) { throw new ArgumentNullException(nameof(connStr)); } if (Settings.App.UseDbConnectionPool) { #region Event handlers void Pool_TryReturnToPoolError(Exception ex, int tryCount) { Log.Error(ex, "Failed {TryCount} time(s) in retrying add DbConnection to pool", tryCount); } void Pool_WatcherThreadError(Exception ex, DbConnection dbConnection) { Log.Error(ex, "Failure on watcher thread with DbConnection of '{ConnStr}'", dbConnection.ConnectionString); } void Pool_NewConnectionError(Exception ex, string poolKey) { Log.Error(ex, "Failure on create connection '{PoolKey}'", poolKey); } void Pool_ReleaseConnectionError(Exception ex, DbConnection dbConnection) { Log.Error(ex, "Failure on disposing DbConnection of '{ConnStr}'", dbConnection.ConnectionString); } #endregion IDbConnectionPoolManager connectionPoolManager; var poolKeyMap = new Dictionary <string, string>(); services.AddSqlConnectionPoolManager(out connectionPoolManager, configAction: options => { options.WatchIntervalInMinutes = SqlConnectionPoolManagerOptions.DefaultWatchIntervalInMinutes; }, initAction: async pool => { pool.TryReturnToPoolError += Pool_TryReturnToPoolError; pool.NewConnectionError += Pool_NewConnectionError; pool.WatcherThreadError += Pool_WatcherThreadError; pool.ReleaseConnectionError += Pool_ReleaseConnectionError; var poolSize = SqlConnectionHelper.ReadPoolSize(connStr); var poolKey = await pool.InitDbConnectionAsync(new ConnectionPoolOptions { ConnectionString = connStr, LifetimeInMinutes = ConnectionPoolOptions.DefaultLifetimeInMinutes, MaximumRetryWhenFailure = ConnectionPoolOptions.DefaultMaximumRetryWhenFailure, RetryIntervalInSeconds = ConnectionPoolOptions.DefaultRetryIntervalInSeconds, MaxPoolSize = poolSize.maxPoolSize, MinPoolSize = poolSize.minPoolSize }); poolKeyMap[DataConsts.ConnStrKey] = poolKey; }).AddDbContext <DataContext>(async builder => { var pooledConn = await connectionPoolManager.GetDbConnectionAsync(poolKeyMap[DataConsts.ConnStrKey]); builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); if (pooledConn != null) { builder.UseSqlServer(pooledConn); } else { builder.UseSqlServer(connStr); } }); } else { services.AddNullConnectionPoolManager() .AddDbContext <DataContext>(options => options .UseSqlServer(connStr) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)); } return(services); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime, IDynamicLinkCustomTypeProvider dynamicLinkCustomTypeProvider, ISecretsManager secretsManager) { // Secrets Settings.Get <JwtSettings>().SecretKey = secretsManager.Get(JwtSettings.ConfigKey); // Configurations app.RegisterOptionsChangeHandlers(typeof(AppSettings), typeof(JwtSettings)); // AutoMapper var mapConfig = new MapperConfiguration(cfg => { cfg.AddMaps(StartupConfig.TempAssemblyList); }); GlobalMapper.Init(mapConfig.CreateMapper()); // Dynamic Linq DynamicLinqConsts.DefaultParsingConfig = new ParsingConfig { CustomTypeProvider = dynamicLinkCustomTypeProvider }; // HttpContext app.ConfigureHttpContext(); #region Serilog if (!_requestLoggingOptions.UseDefaultLogger) { var requestLogger = Configuration.ParseLogger( LoggingConsts.RequestLoggingOptionsKey, app.ApplicationServices); app.UseDefaultSerilogRequestLogging(_requestLoggingOptions, requestLogger); _resources.Add(requestLogger); } else { app.UseDefaultSerilogRequestLogging(_requestLoggingOptions); } #endregion app.UseExceptionHandler($"/{Routing.Controller.Error.Route}"); app.UseRequestFeature(); app.UseStaticFiles(); app.UseHttpsRedirection(); app.UseRequestLocalization(); app.UseRouting(); // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); c.RoutePrefix = string.Empty; c.InjectStylesheet("/custom-swagger-ui.css"); }); app.UseCors(builder => { builder.AllowAnyHeader(); builder.AllowAnyMethod(); builder.AllowCredentials(); //builder.AllowAnyOrigin(); builder.SetIsOriginAllowed(origin => { return(true); }); }); app.UseAuthentication(); app.UseRequestDataExtraction(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // app lifetime appLifetime.ApplicationStarted.Register(OnApplicationStarted); appLifetime.ApplicationStopped.Register(OnApplicationStopped); PrepareEnvironment(env); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime, IDynamicLinkCustomTypeProvider dynamicLinkCustomTypeProvider, ISecretsManager secretsManager) { // Secrets Settings.SecretsManager = secretsManager; Settings.Jwt.SecretKey = secretsManager.Get(JwtSettings.ConfigKey); // Configurations app.RegisterOptionsChangeHandlers(typeof(AppSettings), typeof(JwtSettings), typeof(ApiSettings)); // AutoMapper var mapConfig = new MapperConfiguration(cfg => { cfg.AddMaps(_tempAssemblyList); }); GlobalMapper.Init(mapConfig.CreateMapper()); // Dynamic Linq DynamicLinqEntityTypeProvider.DefaultParsingConfig = new ParsingConfig { CustomTypeProvider = dynamicLinkCustomTypeProvider }; // i18n Time.Providers.Default = Time.Providers.Utc; Time.ThreadTimeZoneProvider = new HttpThreadTimeZoneProvider(); // HttpContext app.ConfigureHttpContext(); // BusinessContext app.ConfigureBusinessContext(); // UnitOfWork app.ConfigureUnitOfWork(); PrepareEnvironment(env); if (env.IsDevelopment()) { // configure dev settings } #region Serilog if (!_requestLoggingOptions.UseDefaultLogger) { _requestLogger = Configuration.ParseLogger( ConfigConsts.Logging.RequestLoggingOptionsKey, app.ApplicationServices); } app.UseDefaultSerilogRequestLogging(_requestLoggingOptions, _requestLogger); #endregion app.UseExceptionHandler($"/{ApiEndpoint.Error}"); app.UseRequestFeature(); app.UseStaticFiles(); app.UseHttpsRedirection(); app.UseRequestLocalization(); app.UseRouting(); // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); c.RoutePrefix = string.Empty; }); app.UseCors(builder => { builder.AllowAnyHeader(); builder.AllowAnyMethod(); builder.AllowCredentials(); //builder.AllowAnyOrigin(); builder.SetIsOriginAllowed(origin => { return(true); }); }); app.UseRequestTimeZone(); app.UseAuthentication(); app.UseRequestDataExtraction(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // app lifetime appLifetime.ApplicationStarted.Register(OnApplicationStarted); appLifetime.ApplicationStopped.Register(OnApplicationStopped); }