Database Factory Implementation In C#

Many developers have confusion about how to write database code in an application. I will discuss several approaches here and try to provide the explanation for each approach.

Approach 1

This is the easiest and very straightforward approach that will work absolutely fine.  I am assuming you already have an understanding of design principles. I am just exploring the different approaches to achieve the database connectivity.

  1. using System.Collections.Generic;  
  2. using System.Data.SqlClient;  
  3. namespace DatabaseFactory {  
  4.     class Program {  
  5.         static void Main(string[] args) {  
  6.             var employees = SomeDabOperation();  
  7.         }  
  8.         private static List < Employee > SomeDabOperation() {  
  9.             using(SqlConnection myConnection = new SqlConnection("connectionString")) {  
  10.                 using(SqlCommand myCommand = new SqlCommand("Select * From Employee", myConnection)) {  
  11.                     using(SqlDataReader reader = myCommand.ExecuteReader()) {  
  12.                         //Some Code.......  
  13.                     }  
  14.                 }  
  15.             }  
  16.             return new List < Employee > ();  
  17.         }  
  18.     }  
  19.     public class Employee {}  

Approach 2

How about the below code? Just a single line! Isn't it more clean than the earlier approach?

Where did the rest of the code get moved? Of course, we can't remove the code and we have just moved it to a separate class.

  1. namespace DatabaseFactory {  
  2.     class Program {  
  3.         static void Main(string[] args) {  
  4.             var employees = DatabaseManager.SomeDabOperation();  
  5.         }  
  6.     }  
  7. }  

We can see the benefit of moving database logic to different layer - we are not bothered if the database will get changed in the future, it's much more readable than before etc.

  1. using System.Collections.Generic;  
  2. using System.Data.SqlClient;  
  3. namespace DatabaseFactory {  
  4.     internal class DatabaseManager {  
  5.         internal static object SomeDabOperation() {  
  6.             using(SqlConnection myConnection = new SqlConnection("connectionString")) {  
  7.                 using(SqlCommand myCommand = new SqlCommand("Select * From Employee", myConnection)) {  
  8.                     using(SqlDataReader reader = myCommand.ExecuteReader()) {  
  9.                         //Some Code.......  
  10.                     }  
  11.                 }  
  12.             }  
  13.             return new List < Employee > ();  
  14.         }  
  15.     }  
  16.     public class Employee {}  
  17. }  

Approach 3

Before writing the cleaner method of Database Factory, let's explore the use of web.cofig/app.config in the implementation.

App.config 

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

Create a class to read custom section

  1. public class DbFactorySectionHandler: ConfigurationSection {  
  2.         public string Name {  
  3.             get {  
  4.                 return (string) base["Name"];  
  5.             }  
  6.         }  
  7.         public string ConnectionStringName {  
  8.             get {  
  9.                 return (string) base["CnnectionStringName"];  
  10.             }  
  11.         }  
  12.         public string ConnectionString {  
  13.             get {  
  14.                 try {  
  15.                     return ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;  
  16.                 } catch (Exception excep) {  
  17.                     throw new Exception("Connection string " + ConnectionStringName + " was not found in web.config. " + excep.Message);  
  18.                 }  
  19.             }  
  20.         }  
  21.     }  
  22.     -- -- -- -- -- -- - Create Database Abstract Class-- -- -- -- -- -- -- -- -- -- --  
  23.     public abstract class DataBase {  
  24.         public string connectionString;#  
  25.         region Abstract Functions  
  26.         public abstract IDbConnection CreateConnection();  
  27.         public abstract IDbCommand CreateCommand();  
  28.         public abstract IDbConnection CreateOpenConnection();  
  29.         public abstract IDbCommand CreateCommand(string commandText, IDbConnection connection);  
  30.         public abstract IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection);  
  31.         public abstract IDataParameter CreateParameter(string parameterName, object parameterValue);#  
  32.         endregion  
  33.     }  
  34.     -- -- -- - Create a Concrete Database class-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
  35.     public class SqlDataBase: DataBase {  
  36.         public override IDbCommand CreateCommand() {  
  37.             return new SqlCommand();  
  38.         }  
  39.         public override IDbCommand CreateCommand(string commandText, IDbConnection connection) {  
  40.             SqlCommand command = (SqlCommand) CreateCommand();  
  41.             command.CommandText = commandText;  
  42.             command.Connection = (SqlConnection) connection;  
  43.             command.CommandType = CommandType.Text;  
  44.             return command;  
  45.         }  
  46.         public override IDbConnection CreateConnection() {  
  47.             return new SqlConnection(connectionString);  
  48.         }  
  49.         public override IDbConnection CreateOpenConnection() {  
  50.             SqlConnection connection = (SqlConnection) CreateConnection();  
  51.             connection.Open();  
  52.             return connection;  
  53.         }  
  54.         public override IDataParameter CreateParameter(string parameterName, object parameterValue) {  
  55.             return new SqlParameter(parameterName, parameterValue);  
  56.         }  
  57.         public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection) {  
  58.             SqlCommand command = (SqlCommand) CreateCommand();  
  59.             command.CommandText = procName;  
  60.             command.Connection = (SqlConnection) connection;  
  61.             command.CommandType = CommandType.StoredProcedure;  
  62.             return command;  
  63.         }  
  64.     }  
  65.     -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --Factory Implementation-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - public sealed class DataBaseFactory {  
  66.         public static DbFactorySectionHandler sectionHandler = (DbFactorySectionHandler) ConfigurationManager.GetSection("DbFactoryConfiguration");  
  67.         private DataBaseFactory() {}  
  68.         public static DataBase CreateDataBase() {  
  69.             if (sectionHandler ? .Name ? .Length == 0) throw new Exception("Database name not defined in DbFactoryConfiguration section of config file");  
  70.             try {  
  71.                 Type database = Type.GetType(sectionHandler.Name);  
  72.                 ConstructorInfo constructorInfo = database.GetConstructor(new Type[] {});  
  73.                 DataBase databaseObj = (DataBase) constructorInfo.Invoke(null);  
  74.                 databaseObj.connectionString = sectionHandler.ConnectionString;  
  75.                 return databaseObj;  
  76.             } catch (Exception excep) {  
  77.                 throw new Exception("Error instantiating database " + sectionHandler.Name + ". " + excep.Message);  
  78.             }  
  79.         }  
  80.     }  
  81.     -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -  
  82.     -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - public class DbWorker {  
  83.         public static DataBase _database = null;  
  84.         static DbWorker() {  
  85.             _database = DataSoreFactory.DataBaseFactory.CreateDataBase();  
  86.         }  
  87.         public DataBase dataBase {  
  88.             get {  
  89.                 return _database;  
  90.             }  
  91.         }  
  92.     }  
  93. Use: SomeClass: DbWorker {  
  94.     dataBase.CreateOpenConnection()  
  95. }