ASP.NET SignalR 與 LayIM2.0 配合輕鬆實現Web聊天室(十一) 代碼重構使用反射工廠解耦

來源:互聯網
上載者:User

標籤:

前言

  自從此部落格發表以及代碼開源以來,得到了許多人的關注。也沒許多吧,反正在我意料之外的。包括幾位大牛幫我做訂閱號推廣,真的很感謝他們。另外,還有幾個高手給我提了一些架構上的問題。其實本身這個項目是沒有做什麼架構設計的。只是簡單分了分層。不過我在經過仔細思考之後決定對項目架構做些調整,當然在我的技術範圍之內,我相信還會有第二次,第三次甚至更多重構,我希望把他變得更加完美。

重構思路

  對於重構思路,我首先想到的是,讓程式能夠支援多種資料庫,比如我現在用的是SQLServer,而好多朋友用MySQL或者mongodb等其他資料庫,本來初衷沒有想這麼多,認為此項目就是一個關於SignalR和LayIM的Demo實現。不過能最佳化一下是最好的。然後我就想到了一個經典的用法,那就是反射工廠。通過反射來動態產生對象,然後調用方法,而不用去改UI的代碼。

  比如,當我同樣寫了一個MySQL的擷取使用者基礎資訊的方法,那麼我就需要去改Controller中的代碼:

  

     public JsonResult GetBaseList(int userid)        {            //SQLServer資料庫調用方法            //var result = LayimUserBLL.Instance.GetChatRoomBaseInfo(userid);            //MySQL資料庫調用方法            //var result = LayimUserBLL_MySQL.Instance.GetChatRoomBaseInfo(userid);            return Json(result, JsonRequestBehavior.AllowGet);        }

  這樣的話要改動的地方太多了,其實重構也很花費時間,但是是值得的。於是我先在BLL層定義了方法介面。

  public interface IUser : ISearch    {        #region 擷取使用者登入聊天室後的基本資料        JsonResultModel GetChatRoomBaseInfo(int userid);        #endregion        #region 擷取群組人員資訊        JsonResultModel GetGroupMembers(int groupid);        #endregion        #region 使用者登入或者註冊流程        /// <summary>        /// 使用者登陸或者註冊,返回使用者id如果為 0 說明密碼錯誤        /// </summary>        /// <param name="loginName"></param>        /// <param name="loginPwd"></param>        /// <param name="nickName"></param>        /// <returns></returns>        int UserLoginOrRegister(string loginName, string loginPwd);        #endregion        #region 使用者建立群        JsonResultModel CreateGroup(string groupName, string groupDesc, int userid);        #endregion        #region 擷取使用者有關的訊息        JsonResultModel GetUserApplyMessage(int userid);        #endregion        #region 擷取某個使用者的好友名單        /// <summary>        /// 擷取某個使用者的好友名單        /// </summary>        /// <param name="userid">使用者ID</param>        /// <returns>返回格式如下 ""或者 "10001,10002,10003"</returns>        string GetUserFriends(int userid);        #endregion        #region 讀取使用者所在的群        string[] GetUserAllGroups(string userId);        #endregion    }

  這樣,我在把原本LayimBLL繼承這個介面,然後相應的改一下代碼。基本不用變,因為我定義這個介面的時候就是參照原類中的方法定義的。同樣,在MySQL檔案夾下同樣建立一個類繼承自這個介面,然後類比一個MySQL的實現。

    public JsonResultModel GetChatRoomBaseInfo(int userid)        {            var result = new BaseListResult();            result.mine = new UserEntity            {                avatar = "/headphotos/default.jpg",                id = 1,                sign = "我來自MySQL",                status = "online",                username = "MySQL"            };            return JsonResultHelper.CreateJson(result, true);        }

  那麼反射工廠做了什麼工作呢。通過讀取設定檔來動態產生相應的對象執行個體。核心代碼就在於Type.GetType方法,然後調用Activator.CreateInstance方法建立執行個體。

  public class LayIMFactory    {        #region 私人變數和方法        readonly string asemmblyPath = "LayIM.BLL.Classes.{0}.{1},LayIM.BLL";        private string InstanceName        {            get { return AppSettings.GetValue("DBType"); }        }        private string GetFullAsemmblyPath(string className)        {            return string.Format(asemmblyPath, InstanceName, className);        }        #endregion        public IUser Create()        {            return Create<IUser>(BLLClasses.User);        }        /// <summary>        /// 通過反射來擷取某個類的執行個體        /// </summary>        /// <typeparam name="IT"></typeparam>        /// <param name="className"></param>        /// <returns></returns>        private IT Create<IT>(string className)        {            var nameSpace = GetFullAsemmblyPath(className);            Type t = Type.GetType(nameSpace);            IT instance = (IT)Activator.CreateInstance(t);            return instance;        }    }

  然後,Controller稍微改動一下。這樣Controller只希望要一個實現IUser介面的執行個體對象,並不關係你內部用的是MySQL還是SQLServer,這樣能夠實現Controller和BLL層解耦的目的。

  

    當然後邊我做的工作很多,代碼就不全粘了。下面運行一下,看看效果。

重構後的代碼示範

  首先設定檔中的,DBType我們把值設為SQLServer.(圖片中的資料是從sqlserver資料庫中讀取的)

  

  然後再將設定檔中的DBType的值改為MySQL(由於尚未開發和MySQL對接,為了類比示範,資料為代碼中寫死的。見上文)

     

 

總結

  哦啦,雖然這個例子稍微有點簡單,但是也比之前的代碼好了一點,代碼重構的過程是很痛苦的,你要推翻你以前寫的好多代碼,甚至整個項目都要重寫。路還長,這個項目也是讓我成長不少,繼續加油。沒有看過此系列的小夥伴可以移步這裡哦:

  ASP.NET SignalR 與 LayIM2.0 配合輕鬆實現Web聊天室 實戰系列(不斷更新中)

ASP.NET SignalR 與 LayIM2.0 配合輕鬆實現Web聊天室(十一) 代碼重構使用反射工廠解耦

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.