Skip to main content

Database Factory Design Pattern C#

Many developers has confusion on how to write database code in application. I will discuss several approaches here and try to provide explanation on each approach.

Approach 1 : Easiest approach which is very straight forward which will work absolutely fine. The issues we will get to manage the project in terms of software principles. Like if you going to change Database provider, you would need to change using statements and other issue like mixing Database code with business logic etc. I will not go in detail here, I am assuming you already have an understanding of design principles. I am just exploring different approaches to achieve the database connectivity.

using System.Collections.Generic;
using System.Data.SqlClient;

namespace DatabaseFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            var employees = SomeDabOperation();
        }

        private static List<Employee> SomeDabOperation()
        {
            using (SqlConnection myConnection = new SqlConnection("connectionString"))
            {
                using (SqlCommand myCommand = new SqlCommand("Select * From Employee", myConnection))
                {
                    using (SqlDataReader reader = myCommand.ExecuteReader())
                    {
                        //Some Code.......
                    }
                }
            }
            return new List<Employee>();
        }
    }
    public class Employee
    {
    }

Approach 2: How about the below code , Just a single line ? Isn't more clean than earlier approach ?

Where the rest of the code got moved ? Ofcource, we can't remove the code and wew have just moved to separate class.

namespace DatabaseFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            var employees = DatabaseManager.SomeDabOperation();
        }
    }

}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
We can see the benefit by moving database logic to different layer, we are not bothered if Database will get changed in future, much readable than before etc.

using System.Collections.Generic;
using System.Data.SqlClient;

namespace DatabaseFactory
{
    internal class DatabaseManager
    {
        internal static object SomeDabOperation()
        {
            using (SqlConnection myConnection = new SqlConnection("connectionString"))
            {
                using (SqlCommand myCommand = new SqlCommand("Select * From Employee", myConnection))
                {
                    using (SqlDataReader reader = myCommand.ExecuteReader())
                    {
                        //Some Code.......
                    }
                }
            }
            return new List<Employee>();
        }
    }
    public class Employee
    {
    }
}

Approach 3 :  Before writing the more cleaner way of Database Factory, let's explore the use of Web.cofig/app.config in the implementation.


App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="DbFactoryConfiguration" type="GuruBook.Store.DbFactorySectionHandler, GuruBook.Store"/>
  </configSections>
  <connectionStrings>
    <clear/>
    <add name="sqlConnectionString" providerName="System.Data.SqlClient" connectionString="DataSource=W10FMV4P72\SQLEXPRESS;Initial Catalog=FitBook;Integrated Security=True;" />
  </connectionStrings>
  <DbFactoryConfiguration Name="GuruBook.Store.DataStores.SqlDataBase" ConnectionStringName="sqlConnectionString" />
</configuration>

Create Class to Read custom section :

public class DbFactorySectionHandler:ConfigurationSection
    {
        public string Name
        {
            get { return (string)base["Name"]; }
        }

        public string ConnectionStringName
        {
            get { return (string)base["CnnectionStringName"]; }
        }

        public string ConnectionString
        {
            get
            {
                try
                {
                    return ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;
                }
                catch (Exception excep)
                {
                    throw new Exception("Connection string " + ConnectionStringName + " was not found in web.config. " + excep.Message);
                }
            }
        }
    }

-------------Create Database Abstract Class----------------------
 public abstract class DataBase
    {
        public string connectionString;
        #region Abstract Functions
        public abstract IDbConnection CreateConnection();
        public abstract IDbCommand CreateCommand();
        public abstract IDbConnection CreateOpenConnection();
        public abstract IDbCommand CreateCommand(string commandText, IDbConnection connection);
        public abstract IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection);
        public abstract IDataParameter CreateParameter(string parameterName, object parameterValue);
        #endregion
    }

-------Create  a Concrete Database class ------------------------------
  public class SqlDataBase : DataBase
    {
        public override IDbCommand CreateCommand()
        {
            return new SqlCommand();
        }

        public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
        {
            SqlCommand command = (SqlCommand)CreateCommand();
            command.CommandText = commandText;
            command.Connection = (SqlConnection)connection;
            command.CommandType = CommandType.Text;
            return command;
        }

        public override IDbConnection CreateConnection()
        {
            return new SqlConnection(connectionString);
        }

        public override IDbConnection CreateOpenConnection()
        {
            SqlConnection connection = (SqlConnection)CreateConnection();
            connection.Open();
            return connection;
        }

        public override IDataParameter CreateParameter(string parameterName, object parameterValue)
        {
            return new SqlParameter(parameterName, parameterValue);
        }

        public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection)
        {
            SqlCommand command = (SqlCommand)CreateCommand();
            command.CommandText = procName;
            command.Connection = (SqlConnection)connection;
            command.CommandType = CommandType.StoredProcedure;
            return command;
        }
    }
--------------------------------------------Factory Implementation-------------------------------
 public sealed class DataBaseFactory
    {
        public static DbFactorySectionHandler sectionHandler = (DbFactorySectionHandler)ConfigurationManager.GetSection("DbFactoryConfiguration");
        private DataBaseFactory()
        {

        }
        public static DataBase CreateDataBase()
        {
            if (sectionHandler?.Name?.Length == 0)
                throw new Exception("Database name not defined in DbFactoryConfiguration section of config file");

            try
            {
                Type database = Type.GetType(sectionHandler.Name);
                ConstructorInfo constructorInfo = database.GetConstructor(new Type[] { });
                DataBase databaseObj = (DataBase)constructorInfo.Invoke(null);
                databaseObj.connectionString = sectionHandler.ConnectionString;
                return databaseObj;
            }
            catch (Exception excep)
            {
                throw new Exception("Error instantiating database " + sectionHandler.Name + ". " + excep.Message);
            }
        }
    }
-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
 public class DbWorker
    {
        public static DataBase _database = null;
        static DbWorker()
        {
            _database = DataSoreFactory.DataBaseFactory.CreateDataBase();
        }

        public DataBase dataBase { get { return _database; } }
    }

Use : 

SomeClass:DbWorker{
  dataBase.CreateOpenConnection()
}

Comments

Popular posts from this blog

Abstract Factory Design Pattern

Abstract Factory : return families of related or dependent objects without specifying their concrete classes. AbstractFactory- IVehicle ConcreteFactory - Maruti, Honda AbstractProduct- IDiesel, IPetrol Product- DezirePetrol, ZenDiesel, AmazeDiesel, CityPetrol Client- This is a class which uses AbstractFactory and AbstractProduct interfaces to create a family of related objects Implementation is pretty much straight forward: Since now you have good understanding of Factory, there is nothing much to explain. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory {     class Program     {         static void Main(string[] args)         {             IVehicle marutiVehicle = new Maruti();             CarClient marutiClient = new CarClient(marutiVehicle); ...

About Us

Ashish Joshi C# TestDome Certificate Hi, Welcome to my blog on various topics on .Net Stack basically. My name is Ashish Joshi and I’m a software developer. I majorly work with .NET. I recently started writing  blogs about .NET but since now .Net Stack is huge and crossing it's boundaries, it's  compatible with other technology stacks, you’ll see posts from other technologies as well. I hope you’ll find a lot of interesting topics here that you can use in your own assignments. You can find me on LinkedIn I am.planning to write in coming days (2017-2018) on: Popular Interview Questions For Experienced .Net resources  MongoDb in .NET Various Design Patterns Machine Learning - will try to demonstrate how it can be done in .net and in other technology Artificial Intelligence - same as machine learning I'll demonstrate using some running examples Feel free to provide your feedback and suggestions.

Privacy Policy

This blog does not share personal information with third parties nor do we store any information about your visit to this blog other than to analyze and optimize your content and reading experience through the use of cookies.  You can turn off the use of cookies at anytime by changing your specific browser settings.  We are not responsible for republished content from this blog on other blogs or websites without our permission.  This privacy policy is subject to change without notice and was last updated on Month, Day, Year. If you have any questions feel free to contact me through comment section of this blog.