循序漸進開發WinForm項目(2)--項目代碼的分析

隨筆背景:在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉到C#開發的,有沒有一些基礎性的資料給我們學習學習呢,你的框架感覺一下太大了,希望有個循序漸進的教程或者視頻來學習就好了。
其實也許我們每天面對的太多東西了,覺得很多都稀松平常了,即使很細微的地方,可能我們都已經形成習慣了。反過來,如果我們切換到其他領域,如IOS、android,那么開始我們可能對里面很多設計的規則不甚了解,開始可能也是一頭霧水。
本篇繼續上一篇《循序漸進開發WinForm項目(1) --數據庫設計和項目框架的生成》,繼續介紹如何循序漸進開發Winform項目,繼續分析介紹Winform的項目代碼,從而讓我們更加了解其中的分層和項目框架的組成等內容。

1、數據訪問接口的定義

上面我們分析了實體類的定義,本節繼續分析其他部分的內容,如數據訪問接口成的定義如下所示。

namespace WHC.TestProject.IDAL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public interface ICustomer : IBaseDAL<CustomerInfo>
    {
    }
}

這里面的代碼很簡單,沒有多余的代碼行,那么里面究竟發生了什么呢,其中的IBaseDAL又是什么定義呢?



其實,IBaseDAL就是定義了很多我們開發用到的基礎接口,如標準的增刪改查,以及衍生出來的一些其他接口,如分頁查詢,條件查詢等接口內容。這個ICustomer就是用來定義一些除了標準接口不能實現外的業務接口。
IBaseDAL通過傳入一個實體類,從而方便給基類接口提供強類型的數據類型指定,提高我們的開發效率,減少出錯的機會。
我們可以在VS里面查看IBaseDAL的定義,如下所示:



可以看到里面很多相關的接口定義,有返回實體T的,也有返回List<T>的,還有DataTable類型等等,這些基礎接口,經過我們多個項目的應用實踐,已逐步穩定并能夠提供很好的接口支持,方便我們快速調用處理。
即使我們在沒有實現任何業務接口的情況下,僅僅利用標準的基類API,也基本上能夠完成絕大多數的數據操作功能了。

2、數據訪問接口實現類的定義

我們分析完IDAL的數據訪問接口成的定義后,繼續了解一下,如何基于這個接口進行訪問層的實現設計的。數據訪問的實現層在項目中的位置如下所示(以基于SqlServer的DALSQL層進行分析)。



它的類代碼定義如下所示。

namespace WHC.TestProject.DALSQL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public class Customer : BaseDALSQL<CustomerInfo>, ICustomer
    {

數據訪問接口實現層和接口定義層一樣,都有一個基類,如基于SqlServer實現的基類為BaseDALSQL,這個基于SqlServer的數據訪問基類,它也是繼承自一個超級基類(大多數的實現在這里)AbstractBaseDAL。他們之間的繼承關系如下所示



而我們剛才在項目工程的圖里面看到,BaseDALSQL、IBaseDAL、AbstractBaseDAL這些類庫由于具有很大的通用性,為了減少在不同的項目中進行復制導致維護問題,因此我們全部把這些經常使用到的基類或者接口,抽取到一個獨立的類庫里面,為了和普通的DotNET公用類庫命名進行區分(WHC.Framework.Commons),我們把它命名為WHC.Framework.ControlUtil。
BaseDALSQL基類的定義如下所示。



這樣做的好處是,在所有的模塊里面,避免復制導致的版本維護問題,同時也減少代碼的重復生成,增量生成的全部代碼,可以一次性復制到整個項目工程里面,而不會導致基礎類庫的替換,因為這些基類不在生成目錄里面,所有生成的類文件,都是和業務表相關的,如下所示。

具體的數據訪問實現類(如Customer),它把數據庫信息轉換為實體類,有一個函數,在代碼生成的時候已經生成;同時在把實體類的屬性保存到數據庫也有一個類似CRM的映射關系,從而實現可空的字段獲取和更新操作。

/// <summary>
/// 將DataReader的屬性值轉化為實體類的屬性值,返回實體類
/// </summary>
/// <param name="dr">有效的DataReader對象</param>
/// <returns>實體類對象</returns>
protected override CustomerInfo DataReaderToEntity(IDataReader dataReader)
{
    CustomerInfo info = new CustomerInfo();
    SmartDataReader reader = new SmartDataReader(dataReader);
    
    info.ID = reader.GetString("ID");
    info.Name = reader.GetString("Name");
    info.Age = reader.GetInt32("Age");
    info.Creator = reader.GetString("Creator");
    info.CreateTime = reader.GetDateTime("CreateTime");
    
    return info;
}

/// <summary>
/// 將實體對象的屬性值轉化為Hashtable對應的鍵值
/// </summary>
/// <param name="obj">有效的實體對象</param>
/// <returns>包含鍵值映射的Hashtable</returns>
protected override Hashtable GetHashByEntity(CustomerInfo obj)
{
    CustomerInfo info = obj as CustomerInfo;
    Hashtable hash = new Hashtable(); 
    
    hash.Add("ID", info.ID);
     hash.Add("Name", info.Name);
     hash.Add("Age", info.Age);
     hash.Add("Creator", info.Creator);
     hash.Add("CreateTime", info.CreateTime);
         
    return hash;
}

3、業務邏輯層的實現分析

分析完成了數據訪問層的接口和實現類后,我們來進一步看看業務邏輯層的實現分析,由于數據訪問層的本意是基于特定的數據庫實現,因此業務邏輯層就是抽象不同的數據庫,讓它們根據配置,指向不同的數據庫實現類,從而實現多數據庫的支持。

namespace WHC.TestProject.BLL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public class Customer : BaseBLL<CustomerInfo>
    {
        public Customer() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
        }
    }
}

業務邏輯層的代碼也很簡單,在構造函數里面Init一下即可,之所以使用這個Init操作,其實為了確定BLL層的業務對象名稱和指定在哪個程序集里面進行構造的需要,讓給基類進行必要的創建工作。

在BaseBLL的Init函數里面,我們根據子類傳入的相關參數,由于我們約定了數據訪問類的命名空間,因此只根據數據庫配置的不同需要,替換部分名稱,就可以具體的構造出一個數據訪問類了。

#region 根據不同的數據庫類型,構造相應的DAL層
AppConfig config = new AppConfig();
string dbType = config.AppConfigGet("ComponentDbType");
if (string.IsNullOrEmpty(dbType))
{
    dbType = "sqlserver";
}
dbType = dbType.ToLower();

string DALPrefix = "";
if (dbType == "sqlserver")
{
    DALPrefix = "DALSQL.";
}
else if (dbType == "access")
{
    DALPrefix = "DALAccess.";
}
else if (dbType == "oracle")
{
    DALPrefix = "DALOracle.";
}
else if (dbType == "sqlite")
{
    DALPrefix = "DALSQLite.";
}
else if (dbType == "mysql")
{
    DALPrefix = "DALMySql.";
}
#endregion

this.dalName = bllFullName.Replace(bllPrefix, DALPrefix);//替換中級的BLL.為DAL.,就是DAL類的全名
baseDal = Reflect<IBaseDAL<T>>.Create(this.dalName, dalAssemblyName);//構造對應的DAL數據訪問層的對象類

這樣精確構造出來的數據庫訪問訪問對象,并把它轉換為基類接口,那么就可以在BaseBLL類里的基類接口進行調用了。
而構造業務對象,通過BLLFactory<T>的泛型工廠,更能夠精確構造出對應的業務對象類,這樣構造出來的對象具有強類型,非常方便使用。


以上就是業務邏輯層,數據訪問層和數據訪問接口層的設計關系,為了高效進行開發工作,我們一定要使用強類型的接口調用,這樣可以大大減少出錯機會,而返回的基類接口,由于傳入了特定的具體類型T,也能夠構造出強類型的列表或者對象。因此,合理利用泛型,能夠是我們的開發體驗更加美好,更加高效。
循序漸進開發WInform項目--系列文章導引:
循序漸進開發WinForm項目(6)--開發使用混合式Winform模塊
循序漸進開發WinForm項目(5)--Excel數據的導入導出操作
循序漸進開發WinForm項目(4)--Winform界面模塊的集成使用
循序漸進開發WinForm項目(3)--Winform界面層的項目設計
循序漸進開發WinForm項目(2)--項目代碼的分析
循序漸進開發WinForm項目(1) --數據庫設計和項目框架的生成

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容