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.