程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Winform開發框架的業務對象統一調用方式

Winform開發框架的業務對象統一調用方式

編輯:關於.NET

在這個紛繁的社會裡面,統一性的特點能夠帶來很多高效的產出、牢固的記憶,這種特征無論對於企 業、個人的開發工作,知識的傳承都有著非常重要的作用,Winfrom框架本身就是基於這個理念而生,從 統一的數據庫設計規則開始,統一的項目格局,統一的業務類、數據訪問類、實體類繼承關系,再到統 一的公用類庫,統一的權限管理模塊,統一的字典管理模塊,統一的附件管理...,理解這些理念和規則 後,再來個終極的統一,框架代碼快速生成--Database2Sharp代碼生成工具。所有的框架(包括傳統 Winform開發框架、WCF開發框架、混合式開發框架、Web開發框架)都融合到這裡來,統一整合各種看似 零散,實則高度滲透的模塊,統一的步伐除了時間、效力外,帶來給我更多的饋贈。本文主要介紹我的 Winform框架(也包括其他框架的特點)的業務對象統一調用的方式,介紹如何通過BLLFactory或者 CallerFactory的公用類庫來實現各種業務對象的創建工作。

1、BLLFactory的對象統一調用規則

在我的框架裡面,所有的業務類調用都是以BLLFactory入口進行開始創建,傳遞業務對象進去即可創 建,這種統一入口的方式能夠方便記憶,並減少代碼,更重要的是能夠很好把一些如緩存規則、創建規 則封裝起來,簡化代碼。BLLFactory的創建示意圖如下所示。

既然是統一調用規則方式,那麼BLLFactory的類庫就應該提升到公用類庫的級別,所以提供Winform 框架支持的公用類庫如下所示。

當然,為了減少代碼,提高開發效率,整體的框架處處體現了代碼重用的規則,盡可能把重復的代碼 提取出來,因此還有很多如數據訪問基類、業務訪問基類、數據訪問基類接口、實體基類等類庫,結合 泛型能夠使我們的API更加統一化、強類型化,提高開發效率。由於BLLFactory是公用類庫級別,所有獨 立開發的模塊,也都是以該類庫為統一入口,創建所必須的對象。

我們看看框架如何能夠在紛繁復雜的類庫裡面,准確創建一系列的對象的。

BLLFactory業務對象工廠輔助類的代碼如下所示。

/// <summary>
    /// 對業務類進行構造的工廠類
    /// </summary>
    /// <typeparam name="T">業務對象類型</typeparam>
    public class BLLFactory<T> where T : class
    {
        private static Hashtable objCache = new Hashtable();
        private static object syncRoot = new Object();
    
        /// <summary>
        /// 創建或者從緩存中獲取對應業務類的實例
        /// </summary>
        public static T Instance
        {
            get
            {
                string CacheKey = typeof(T).FullName;
                T bll = (T)objCache[CacheKey];  //從緩存讀取  
                if (bll == null)
                {
                    lock (syncRoot)
                    {
                        if (bll == null)
                        {
                            bll = Reflect<T>.Create(typeof(T).FullName, typeof(T).Assembly.GetName().Name); //反射創建,並緩存
                            objCache.Add(typeof(T).FullName, bll);
                        }
                    }
                }
                return bll;
            }
        }
    }

其中利用了哈希表對象對創建的對象進行緩存,並進一步傳遞參數給Reflect公用類庫,對指定對象 全名、程序集的業務對象進行創建。

以上只是很薄的一層關系,一般我們都能夠很容易理解,但是我們知道,每個業務對象類,還需要負 責創建裡面的數據訪問基類(如IUser接口的數據訪問基類userDal),我們來繼續分析BaseBLL對象的工 作邏輯,才能很好理解其中的關系。

/// <summary>
    /// 用戶信息業務管理類
    /// </summary>
    public class User : BaseBLL<UserInfo>
    {
        private IUser userDal;
    
        public User() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
            this.userDal = (IUser)base.baseDal;
        }
        ..............................
    
    }

其中Init的函數接口定義如下,主要就是根據相關參數,構建數據不同的數據訪問對象,如 SqlServer的訪問對象,或者Oracle的數據訪問對象等。

/// <summary>
        /// 參數賦值後,初始化相關對象
        /// </summary>
        /// <param name="bllFullName">BLL業務類的全名(子類必須實現),子類構造函數傳入this.GetType().FullName</param>
        /// <param name="dalAssemblyName">數據訪問層程序集的清單文件的文件名,不包括其擴展名,可使用Assembly.GetExecutingAssembly().GetName().Name</param>
        /// <param name="bllPrefix">BLL命名空間的前綴(BLL.)</param>
        void Init(string bllFullName, string dalAssemblyName, string bllPrefix = "BLL.")

由於數據訪問也是基於反射方式(帶緩存)創建,因此需要知道數據訪問類的全名和對應的程序集, 如果整合在一個項目工程裡面,如我的框架結構代碼所示,那麼dalAssemblyName就是 System.Reflection.Assembly.GetExecutingAssembly().GetName().Name了。其中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數據訪問層的對象類

由於BLLFactory<T>通過傳入指定的業務對象,成功創建後,會返回相關聯的類的實例,因此 接口的調用在設計時就知道了,也就是上面例子裡面的BLLFactory<BLL.User>.Instance就是 BLL.User類的實例,具有所有該類的接口方法,實現了強類型API的目的了。

下面就是該類在實際界面項目裡面的使用例子代碼。

try
                {
                    UserInfo info = BLLFactory<User>.FindByID(currentID) as UserInfo;
                    if (info != null)
                    {
                        info = SetUserInfo(info);
                        BLLFactory<User>.Instance.Update(info, info.ID.ToString());
                        RefreshTreeView();
    
                        MessageDxUtil.ShowTips("資料保存成功");
                    }
                }
                catch (Exception ex)
                {
                    LogTextHelper.Error(ex);
                    MessageDxUtil.ShowError(ex.Message);
                }

2、CallerFactory的對象統一調用規則

CallerFactory對象是用於創建基於Facade層接口的業務對象,主要用在我的WCF開發框架、混合式開 發框架裡面,該對象的創建邏輯類似於BLLFactory,不過它創建的對象,可能是基於WCF客戶代理的對象 ,也可能是對BLLFactory創建對象的進一步封裝,以便實現宏觀上的統一。如下圖所示,CallerFactory 處在下面框架結構圖的中間部分,UI層的下面。

CallerFactory的調用代碼例子如下所示。

{
                    UserInfo info = CallerFactory<IUserService>.Instance.FindByID(currentID);
                    if (info != null)
                    {
                        info = SetUserInfo(info);
                        CallerFactory<IUserService>.Instance.Update(info, info.ID.ToString());
                        RefreshTreeView();
    
                        MessageDxUtil.ShowTips("資料保存成功");
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                    MessageDxUtil.ShowError(ex.Message);
                }

查看本欄目

我們看到,雖然上面的代碼是基於WCF的分布式應用,我們還是可以看到,這個調用的思路和方式, 和傳統Winform的BLLFactory如出一轍,能解決對象調用問題的同時,這樣的操作方式,能夠給我們學習 框架提供了更好的統一模式,順利切換,而且,從傳統Winfrom開發框架的界面代碼遷移到分布式應用的 WCF開發上,界面代碼的變化也是很有規律的,這就是統一模式的力量和奧妙所在。

和BLLFactory裡面傳入的業務層對象不同,這裡CallerFactory裡面傳入的對象是Facade層的接口, 那麼它是如何知道我們要創建的對象,並把它轉換為我們需要的接口的呢?

/// <summary>
    /// 混合式框架或WCF框架中針對不同調用方式的工廠類(WCF或者Win調用)
    /// </summary>
    /// <typeparam name="T">接口類型</typeparam>
    public class CallerFactory<T>
    {
        private static Hashtable objCache = new Hashtable();
        private static object syncRoot = new Object();
        private static string callerNamespace = null;//Facade接口實現類的命名空間
    
        /// <summary>
        /// 創建或者從緩存中獲取對應接口的實例
        /// </summary>
        public static T Instance
        {
            get
            {
                string CacheKey = typeof(T).FullName;
                T bll = (T)objCache[CacheKey];  //從緩存讀取  
                if (bll == null)
                {
                    lock (syncRoot)
                    {
                        if (bll == null)
                        {
                            bll = CreateObject(); //反射創建,並緩存
                            if (bll != null)
                            {
                                objCache.Add(typeof(T).FullName, bll); //緩存BLL業務對象
                            }
                        }
                    }
                }
                return bll;
            }
        }

從上面的代碼我們看到,這裡的創建邏輯和BLLFactory很大程度的相同,只是細節部分,我使用了 CreateObject 進行了隔離,放到獨立的函數裡面進行創建了。

CreateObject 函數主要邏輯就是根據WCF框架配置信息,到具體的程序集裡面創建對應的對象實例, 然後轉換為Facade層接口,方便統一調用。這就是我WCF開發框架和混合式開發框架,統一調用接口進行 通訊獲取或提交數據的工作模式。

以上就是我Winform開發框架、WCF開發框架、混合式開發框架、Web開發框架裡面所用到的兩種方式 的對象創建方式的說明,希望您能從統一的調用方式可以看到更多的奧妙及好處。

關於以上幾種框架的定義說明,請查看下面圖示的介紹,打開圖示可以查看更多的框架介紹內容。

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

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