程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 循序漸進開發WinForm項目(2) 項目代碼的分析

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

編輯:關於.NET

在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉到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,也能夠構造出強類型的列表或者對象。因此,合理利用泛型,能夠是我們的開發體驗更加美好,更 加高效。

伍華聰  http://www.iqidi.com

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved