Sep 22 2006

Interface to Data Access Layer - howto part 10

Posted by admin under In practice

Please read this article serie from the beginning

In this step - lets look back on the project so far. Remember our save button click event handler in editcust.aspx?



        if (Page.IsValid)
        {
            int lId = -1;
            if (Request["id"] != null)
                lId = Convert.ToInt32(Request["id"]);

            lId = CustomerClasses.Customer.Save(lId,
                txtName.Text);


We call our static function Save in our CustomerClasses.Customer class (located in our business layer dll) - looking like this:



        public static int Save( long lId, string sName )
        {
            SqlParameter[] paramsToSP = new SqlParameter[2];
            paramsToSP[0] = new SqlParameter("@id", SqlDbType.Int);
            paramsToSP[0].Value = lId;
            paramsToSP[1] = new SqlParameter("@name", SqlDbType.VarChar, 50);
            paramsToSP[1].Value = sName;


            return Convert.ToInt32(Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["MainConn"].ToString(),
                CommandType.StoredProcedure, "cust_SaveCustomer", paramsToSP));
        }


Now, this is the problem we are gonna fix now. The CustomerClasses dll is supposed to be our business class layer - and therefore only contain "business related" functionality. Saving to database is NOT business functionality, but rather a technical issue and therefore we need to move such code away from those classes.

Our CustomerClasses.Customer save method should instead look something like this:



        public static int Save( long lId, string sName )
        {
            return DALClasses.Save_Customer( ConfigurationManager.ConnectionStrings["MainConn"].ToString(),
				lId, sName );
                );
        }




So our goal here is to create a new DLL for the DAL (data access layer). But we are actually gonna go one step further - we are gonna resolve which DAL DLL to use in runtime - and open up the possibility to afterhand write new DAL:s (for MySQL, Access etc) and just plug it into our application!

So how it that possible? Well besides the techniques around dynamically loading dll:s - how will the code in the Save function look - since we doesn't know (and doesn't want to know - at least when coding) what DAL class we will be using. If there was a way to define a certain behaviour - saying "we want all possible DAL:s to support the following functions: Customer_Save(long lId, string sName), Customer_Delete(...) etc" - it might be possible?   And there is: enter the concept of interfaces!

Here's the deal. We define an interface in a new dll project - called CustomerInterfaces:



namespace CustomerInterfaces
{
    public interface DALInterface
    {
        long Customer_Save(string sConnString, long lId, string sName);
        DataSet Customer_Open(string sConnString, long ld);
        DataSet Customer_ListAll(string sConnString);



Now we create a new DLL project, calling it CustomerDAL_SQLServer. We set a reference the CustomerInterfaces dll. We create a class, DataAccess, and say it's gonna implement the interface CustomerInterfaces.DALInterface



namespace CustomerDAL_SQLServer
{
    public class DataAccess : CustomerInterfaces.DALInterface
    {
        #region DALInterface Members

        public long Customer_Save(string sConnString, long lId, string sName)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public System.Data.DataSet Customer_Open(string sConnString, long ld)
        {
            SqlParameter[] paramsToSP = new SqlParameter[1];
            paramsToSP[0] = new SqlParameter("@id", SqlDbType.Int);
            paramsToSP[0].Value = id;
            return Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteDataset(sConnString,
                CommandType.StoredProcedure, "cust_OpenCust", paramsToSP);
        }

        public System.Data.DataSet Customer_ListAll(string sConnString)
        {
            throw new Exception("The method or operation is not implemented.");
        }


Now lets keep on implementing the functions (above I had implemented Customer_Open). Basically it's just a matter of moving the code out from the CustomerClasses classes into this DAL project.

This article doesn't have a download - it will be available in the next one instead.