Skip to main content

This class is meant to reduce the amount of repeated code in database provider classes by pulling all the common actions into one spot.

using System;
using System.Configuration;
using System.Data;
using System.Data.Common;

namespace Helpers
{
    /// <summary>
    /// Helper class for working with DbConnections.
    /// </summary>
    /// <remarks>
    /// This class is meant to reduce the amount of repeated code in database
    /// provider classes by pulling all the common actions into one spot.
    ///
    /// This should remove the many repetitive null checks on connections/parameters.
    ///
    /// This class handles the creation of DbConnection, setting its connection
    /// string, and opening the connection if possible.
    ///
    /// Usage is simple:
    ///
    /// using(var helper = new ConnectionHelper(provider)) {
    ///     if (helper.HasConnection) {
    ///         // do stuff
    ///     }
    /// }
    ///
    /// </remarks>
    public sealed class DbConnectionHelper : IDisposable
    {
        private bool _isDisposed;

        /// <summary>
        /// Creates a new DbConnectionHelper instance from the
        /// given ConnectionStringSettings.
        /// </summary>
        /// <param name="settings"></param>
        public DbConnectionHelper(ConnectionStringSettings settings) : this(settings.ProviderName, settings.ConnectionString)
        {
        }

        /// <summary>
        /// Creates a new DbConnectionHelper instance from the given provider name and database connection string..
        /// </summary>
        /// <param name="providerName"></param>
        /// <param name="connectionString"></param>
        public DbConnectionHelper(string providerName, string connectionString)
        {
            Provider = DbProviderFactories.GetFactory(providerName);
            Connection = Provider.CreateConnection();

            HasConnection = (Connection != null);
            if (HasConnection)
            {
                DbConnection dbConnection = Connection;
                if (dbConnection != null)
                {
                    dbConnection.ConnectionString = connectionString;
                    dbConnection.Open();
                }
            }
        }

        /// <summary>
        /// Returns the DbConnection of this instance.
        /// </summary>
        public DbConnection Connection { get; private set; }

        /// <summary>
        /// Gets whether the Connection of this ConnectionHelper instance is null.
        /// </summary>
        public bool HasConnection { get; private set; }

        /// <summary>
        /// Gets the DbProviderFactory used by this ConnectionHelper instance.
        /// </summary>
        public DbProviderFactory Provider { get; private set; }

        /// <summary>
        /// Uses this ConnectionHelper instance's connection to create and return a new DbCommand instance.
        /// </summary>
        /// <returns></returns>
        public DbCommand CreateCommand()
        {
            CheckDisposed();

            return Connection.CreateCommand();
        }

        /// <summary>
        /// Users this ConnectionHelper instance's connection to create and return a new
        /// DbCommand with the given command text. CommandType is automatically set to
        /// CommandType.Text.
        /// </summary>
        /// <param name="commandText"></param>
        /// <returns></returns>
        public DbCommand CreateTextCommand(string commandText)
        {
            DbCommand command = CreateCommand();
            command.CommandText = commandText;
            command.CommandType = CommandType.Text;

            return command;
        }

        public DbCommand CreateStoredProcedureCommand(string storedProcedureName)
        {
            DbCommand command = CreateCommand();
            command.CommandText = storedProcedureName;
            command.CommandType = CommandType.StoredProcedure;

            return command;
        }

        /// <summary>
        /// Uses this ConnectionHelper's Provider to create a DbParameter instance with the given parameter name and value.
        /// </summary>
        /// <param name="parameterName">The name of the parameter.</param>
        /// <param name="value">The value of the parameter.</param>
        /// <returns></returns>
        public DbParameter CreateParameter(string parameterName, object value)
        {
            return CreateParameter(parameterName, value, null, null);
        }

        /// <summary>
        /// Uses this ConnectionHelper's Provider to create a DbParameter instance with the given parameter name and value.
        /// </summary>
        /// <param name="parameterName">The name of the parameter.</param>
        /// <param name="value">The value of the parameter.</param>
        /// <param name="dbType">The DB type.</param>
        /// <returns></returns>
        public DbParameter CreateParameter(string parameterName, object value, DbType dbType)
        {
            return CreateParameter(parameterName, value, dbType, null);
        }

        /// <summary>
        /// Uses this ConnectionHelper's Provider to create a DbParameter
        /// instance with the given parameter name and value.
        /// </summary>
        /// <param name="parameterName">The name of the parameter.</param>
        /// <param name="value">The value of the parameter.</param>
        /// <param name="dbType">The DB type.</param>
        /// <param name="size">The size/length of the parameter.</param>
        /// <returns></returns>
        public DbParameter CreateParameter(string parameterName, object value, DbType? dbType, int? size)
        {
            CheckDisposed();

            DbParameter param = Provider.CreateParameter();

            if (param == null)
            {
                throw new NullReferenceException("DbProvider");
            }

            param.ParameterName = parameterName;
            param.Value = value;

            if (dbType.HasValue)
            {
                param.DbType = dbType.Value;
            }

            if (size.HasValue)
            {
                param.Size = size.Value;
            }

            return param;
        }

        /// <summary>
        /// Disposes this DbConnectionHelper and its underlying connection.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void CheckDisposed()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException("ConnectionHelper");
            }
        }

        private void Dispose(bool disposing)
        {
            try
            {
                if (!_isDisposed && disposing)
                {
                    if (Connection != null)
                    {
                        Connection.Dispose();
                    }
                }
            }
            finally
            {
                Provider = null;
                Connection = null;
                HasConnection = false;
                _isDisposed = true;
            }
        }
    }
}