Beispiel #1
0
        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);
        }