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); }