/// <summary>
        /// Acquires a connection from the pool. Ensures it's open. Invokes the action.
        /// Ensures the connection is returned to the pool when the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <typeparam name="TConnection">The connection type.</typeparam>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        /// <param name="cancellationToken">An optional cancellation token.</param>
        public static async ValueTask OpenAsync <TConnection>(this IDbConnectionPool <TConnection> connectionPool, Func <TConnection, ConnectionState, ValueTask> action, CancellationToken cancellationToken = default)
            where TConnection : IDbConnection
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                await action(conn,
                             await conn.EnsureOpenAsync(cancellationToken))
                .ConfigureAwait(false);
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
        /// <summary>
        /// Acquires a connection from the pool, returning it after the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        public static async ValueTask UsingAsync(this IDbConnectionPool connectionPool, Func <IDbConnection, ValueTask> action)
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                await action(conn).ConfigureAwait(false);
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
        /// <summary>
        /// Acquires a connection from the pool, returning it after the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        public static void Using(this IDbConnectionPool connectionPool, Action <IDbConnection> action)
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                action(conn);
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
        /// <summary>
        /// Acquires a connection from the pool, returning it after the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <typeparam name="T">The type returned from the action.</typeparam>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        /// <returns>The value from the action.</returns>
        public static T Using <T>(this IDbConnectionPool connectionPool, Func <IDbConnection, T> action)
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                return(action(conn));
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
        /// <summary>
        /// Acquires a connection from the pool, returning it after the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <typeparam name="TConn">The connection type.</typeparam>
        /// <typeparam name="T">The type returned from the action.</typeparam>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        /// <returns>The value from the action.</returns>
        public static async ValueTask <T> UsingAsync <TConn, T>(this IDbConnectionPool <TConn> connectionPool, Func <TConn, ValueTask <T> > action)
            where TConn : IDbConnection
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                return(await action(conn).ConfigureAwait(false));
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
        /// <summary>
        /// Acquires a connection from the pool. Ensures it's open. Invokes the action.
        /// Ensures the connection is returned to the pool when the action is complete.
        /// Useful for single-line operations.
        /// </summary>
        /// <typeparam name="TConnection">The connection type.</typeparam>
        /// <param name="connectionPool">The connection pool to acquire connections from.</param>
        /// <param name="action">The action to execute.</param>
        public static void Open <TConnection>(this IDbConnectionPool <TConnection> connectionPool, Action <TConnection, ConnectionState> action)
            where TConnection : IDbConnection
        {
            if (connectionPool is null)
            {
                throw new ArgumentNullException(nameof(connectionPool));
            }
            if (action is null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            Contract.EndContractBlock();

            var conn = connectionPool.Take();

            try
            {
                action(conn, conn.EnsureOpen());
            }
            finally
            {
                connectionPool.Give(conn);
            }
        }
 public void Give(IDbConnection connection)
 => _source.Give(connection);