Club Manager : Data Context

Hmm our configuration is ready, now we can write our Data layer. But how do we begin. As discussed earlier our application is going to be database independent (ie it should be able to run on any database without much effort), so it need to have some generic code to handle all kind of database. We will name this project Core.Data which will be responsible for generic Data handling and our main application will binded to this project.

Go ahead and add a new Dynamic Class Library project Core.Data in Core solution folder, delete Class1.cs and add a new class Core.Data.Context.cs.

Every database generally has following properties :

Host: Host name/ip of database server
Port: Port on which database is running
Auth: Is there any authorization
Username: Username if Auth is true
Password: Password if Auth is true
DBName: Name of the database
Prefix: Prefix to be used in table names
Suffix: Suffix to be used in table names

Since our Context is independent of database type so we also store the type of database in Type. And we will be storing all our configuration in a table whose name is retrieved from ConfigTable. So create static properties for the same. As we did in our Core.Configuration.ConfigurationManager we will store XML Keys as static strings so that we can refer them later and will have same name as above prefixed with DB_ and most important our configuration will be stored under DB node. We want to have methods to list all, addnew, save, and list objects satisfying where clause, but the implementation will be database specific so we mark these methods as abstract and mark the class as abstract as well. As said we have the functionality to have prefix and suffix in the table names so get a method to return final table name as GetTableName(string table). We will be creating Context object as soon as the same is required and the type of final object is determined from Type property so we should have a method(or property) to get the Assembly Name and Class Name from Type. We should also have some convention in naming the Assembly and classes so that we can find the required class to create object. We will be using Core.Data.<Type> as Project name and Core.Data.<Type>.<Type> as the class. Finally we are going to read the XML Node in static constructor and create database connection object as well there and store it for further use.

  • Add XML Configuration keys as private static members
  • Add data properties as protected static members
  • Add abstract methods
  • Add GetTableName
  • Add AssemblyName and ClassName property
  • Add Context object
  • Add static constructor to read and populate values from config xml

Satisfying above listed items find below the generated code:

using System.Collections.Generic;
using System.Reflection;
using System.Xml.Linq;
using Core.Configuration;
 
namespace Core.Data
{
    public abstract class Context
    {
        #region Data Properties
 
        /// <summary>
        /// Hostname of Database
        /// </summary>
        protected static string Host { get; set; }
 
        /// <summary>
        /// Port of Database
        /// </summary>
        protected static int Port { get; set; }
 
        /// <summary>
        /// Authentication true or false
        /// </summary>
        protected static bool Auth { get; set; }
 
        /// <summary>
        /// Username for database authentication
        /// </summary>
        protected static string Username { get; set; }
 
        /// <summary>
        /// Password to be used for authentication
        /// </summary>
        protected static string Password { get; set; }
 
        /// <summary>
        /// Name of the database
        /// </summary>
        protected static string DBName { get; set; }
 
        /// <summary>
        /// Prefix to be added to table names
        /// </summary>
        protected static string Prefix { get; set; }
 
        /// <summary>
        /// Suffix to be added to table names
        /// </summary>
        protected static string Suffix { get; set; }
 
        /// <summary>
        /// Type of database we are using
        /// </summary>
        protected static string Type { get; set; }
 
        /// <summary>
        /// Name of the config table without Prefix/Suffix
        /// </summary>
        protected static string ConfigTable { get; set; }
        #endregion Data Properties
 
        #region XML Configuration Keys
 
        /// <summary>
        /// Key for Database settings in XML Node
        /// </summary>
        private static string DB_KEY = "DB";
 
        /// <summary>
        /// Key to get Hostname from XML node
        /// </summary>
        private static string DB_HOST = "Host";
 
        /// <summary>
        /// Key to get Port from XML node
        /// </summary>
        private static string DB_PORT = "Port";
 
        /// <summary>
        /// Key to get Authentication settings from XML node
        /// </summary>
        private static string DB_AUTH = "Auth";
 
        /// <summary>
        /// Key to get Username from XML node
        /// </summary>
        private static string DB_USERNAME = "Username";
 
        /// <summary>
        /// Key to get Password from XML node
        /// </summary>
        private static string DB_PASSWORD = "Password";
 
        /// <summary>
        /// Key to get Database Name from XML node
        /// </summary>
        private static string DB_DBNAME = "DBName";
 
        /// <summary>
        /// Key to get Prefix from XML node
        /// </summary>
        private static string DB_PREFIX = "Prefix";
 
        /// <summary>
        /// Key to get Suffix from XML node
        /// </summary>
        private static string DB_SUFFIX = "Suffix";
 
        /// <summary>
        /// Key to get Database Type from XML node
        /// </summary>
        private static string DB_TYPE = "Type";
 
        /// <summary>
        /// Key to get Name of Configuration Table from XML node
        /// </summary>
        private static string DB_CONFIGTABLE = "ConfigTable";
 
        #endregion XML Configuration Keys
 
        #region Private Properties
        private static string AssemblyName
        {
            get
            {
                return string.Format("Core.Data.{0}.dll", Type);
            }
        }
        private static string ClassName
        {
            get
            {
                return string.Format("Core.Data.{0}.{0}", Type);
            }
        }
        #endregion Private Properties
 
        #region Abstract Methods
 
        public abstract List<T> ListAll<T>(string table);
 
        public abstract void AddNew<T>(T record, string table);
 
        public abstract void Save<T>(T record, string table);
 
        public abstract List<T> Where<T>(string query, string table);
 
        public abstract string GetID(string key);
 
        #endregion Abstract Methods
 
        #region Context Object
        public static Context DB = null;
        #endregion Context Object
 
        #region Constructors
 
        static Context()
        {
            XElement ele = ConfigurationManager.ConfigValue[DB_KEY];
            Host = ele.Element(DB_HOST).Value;
            Port = ele.Element(DB_PORT).Value.ToInt32();
            Auth = ele.Element(DB_AUTH).Value.ToBoolean();
            Username = ele.Element(DB_USERNAME).Value;
            Password = ele.Element(DB_PASSWORD).Value;
            DBName = ele.Element(DB_DBNAME).Value;
            Prefix = ele.Element(DB_PREFIX).Value;
            Suffix = ele.Element(DB_SUFFIX).Value;
            Type = ele.Element(DB_TYPE).Value;
            ConfigTable = ele.Element(DB_CONFIGTABLE).Value;
 
            DB = (Context)Assembly.LoadFrom(AssemblyName).CreateInstance(ClassName);
        }
 
        #endregion Constructors
 
        #region Protected Members
 
        protected static string GetTableName(string table)
        {
            return Prefix + table + Suffix;
        }
 
        #endregion Protected Members
    }
}

Leave a Reply