namespace PetShop.DALFactory:
我們已經很清楚的知道:PetShop4中的數據訪問層採用的是典型的工廠模式設計,而實現工廠模式的項目就是DALFactory,該項目中只有一個封裝類(sealed):DataAccess,封裝表明該類不能被繼承,原代碼中對類的描述如下:
/// <summary>
/// This class is implemented following the Abstract Factory pattern to create the DAL implementation
/// specified from the configuration file
/// </summary>
該類根據配置文件的設置,應用抽象工廠模式,來創建特定的DAL實例。
一開始,就讀取配置文件,以確定要使用的DAL實例:
// Look up the DAL implementation we should be using
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];
使用readonly來限定,以確定不會無意修改變量。
在配置文件中,我們查到:
<add key="WebDAL" value="PetShop.SQLServerDAL"/>
<add key="OrdersDAL" value="PetShop.SQLServerDAL"/>
接着,是創建各種對象的靜態(static)函數,這表明我們不能通過實例來引用這些靜態函數,只能通過類來調用。有意思的是,這些函數將根據path變量的值,動態確定要創建的實例對象,如在CreateCategory()函數中有:
public static PetShop.IDAL.ICategory CreateCategory() {
string className = path + ".Category";
return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
}
首先,確定要實例化的類名:className=”PetShop.SQLServerDAL.Category”,然後通過:Assembly.Load(path).CreateInstance(className)實現類的實例化,由於PetShop.SQLServerDAL.Category類實現了ICategory接口,因爲可以強制轉化爲PetShop.IDAL.ICategory類型。這樣就達到了“根據配置情況,自動實例化相關的子類,並以該類父類的形式返回該類的實例,對外實現了統一調用,統一返回值”的目標,實現了“工廠模式”的接口。
在DataAccess類的成員如下圖如示:
namespace PetShop.SQLServerDAL:
在該項目中,有如下圖所示的類:
這5個類分別對應數據庫MSPetShop4中的4個業務表:
及數據庫MSPetShop4Orders中的1個業務表:
前面提到了PetShop.SQLServerDAL.Category類,下面我們順着代碼研究一下該類。
Category類繼承自ICategory接口,因此,它必將實現ICategory接口(位於IDAL項目中)中的方法。
一開始聲明瞭三個常量,用於查詢數據的SQL語句:
private const string SQL_SELECT_CATEGORIES = "SELECT CategoryId, Name, Descn FROM Category";
private const string SQL_SELECT_CATEGORY = "SELECT CategoryId, Name, Descn FROM Category WHERE CategoryId = @CategoryId";
private const string PARM_CATEGORY_ID = "@CategoryId";
接着,實現ICateory中的方法:
/// Method to get all categories
public IList<CategoryInfo> GetCategories() {
IList<CategoryInfo> categories = new List<CategoryInfo>();
//Execute a query to read the categories
using(SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORIES, null)) {
while (rdr.Read()) {
CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
categories.Add(cat);
}
}
return categories;
}
GetCategories()方法是一個公開的方法,返回一個IList<CategoryInfo>的泛形值(詳見下文),在執行查詢的過程中,使用了using語句塊,把需要釋放資源的對象的聲明放到using塊的括號內,以保證系統在代碼退出該塊時釋放資源。如果正在使用消耗大量內存或其他組件也需要使用的系統資源時,這樣處理十分有用。using塊的括號內使用SqlHelper類(位於DBUnility項目中)中的ExecuteReader方法,返回一個SqlDataReader類型的對象。查詢的數據保存在此SqlDataReader對象中。接下來,調用對象的Read()方法,將數據行中的前三列數據一行一行的取出來,保存到CategoryInfo類型的對象中,用於返回。
上文中提到的IList<T>接口,是一個表示可按照索引單獨訪問的一組對象。<CategoryInfo>表示該組對象的類型是CategoryInfo型的。CategoryInfo是一個類,位於Model(Business entity used to model a product)項目中,對應於數據庫中的Category表,它是表在系統中的業務實體模型。對於PetShop4中的四個數據庫中的所有業務表,在Model項目中都有與之相對應的業務實體模型(類)。具體如下圖:
CatagoryInfo類中的成員如下圖所示:
包括兩個構造函數,三個屬性對應三個字段。從rdr中取出的數據行就是通過第二個構造函數保存到對象中去的。一行對應一個CatagoryInfo對象。
摘自:http://www.cnblogs.com/luckeryin/archive/2009/01/10/1373390.html