分享CommunityServer(7) –CSModule

來源:互聯網
上載者:User
 

 CSModule實現的事件監聽體系CS裡面的CSModule是個什麼東東?我們知道,系統大了,必然是比較複雜,系統內部很多事件需要被各個相互聯絡的模組相互截取,相互瞭解。我們要針對CS系統做出開發,實際上我們很大程度上是針對CS內部流程執行過程中的大量事件進行面向事件的處理代碼編寫。譬如,我們要做到系統發生了例外,我們可以敏感接獲到,並且需要在特定的“安全區域”進行處理例外;再比如,我們有時候會針對某個文章進行監控,如果發生了新帖需要被通知,如果寫入程式碼進入當然可以,但是假若需要接獲新帖通知的不止一個相關體系,那麼寫入程式碼顯然不符合要求,這樣,就需要一種協調機制,引入一種訊息通告模型,讓內部事件可以通過這種機制安全有序轉入到關心事件的處理部分,這種機制在CS中就是通過CSModule來實現的。 CSEvent 定義了系統內大部分事件。包含了Users、Posts、Sections、Groups、PostCategories、Ratings、Favorites、Exceptions、Search、UserInvitations等對象的事件。但是每一個事件都是調用了CSApplication執行個體的相應事件函數。如關於Search的事件:        public static void PreSearch(SearchQuery query)       {            CSApplication.Instance().ExecutePreSearch(query);        }         public static void PostSearch(SearchResultSet results)        {            CSApplication.Instance().ExecutePostSearch(results);        } 這些事件需要在特定代碼流中被觸發,而這些事件會轉入到 CSApplication的執行個體中。CSApplication是單例模式,並且通過CSCache緩衝執行個體。其Instance函數:internal static CSApplication Instance()         {              const string key = "CSApplication";              CSApplication app = CSCache.Get(key) as CSApplication;              if(app == null)              {                   lock(sync)                   {                       app = CSCache.Get(key) as CSApplication;                       if(app == null)                       {                            CSConfiguration config = CSContext.Current.Config;                            XmlNode node = config.GetConfigSection("CommunityServer/CSModules");                            app = new CSApplication();                            if(node != null)                            {                                 foreach(XmlNode n in node.ChildNodes)                                 {                                      if(n.NodeType != XmlNodeType.Comment)                                     {                                          switch(n.Name)                                          {                                               case "clear":                                                    app.modules.Clear();                                                   break;                                               case "remove":                                            XmlAttribute removeNameAtt = n.Attributes["name"];                                            string removeName = removeNameAtt == null ? null : removeNameAtt.Value;                                             if(!Globals.IsNullorEmpty(removeName) && app.modules.ContainsKey(removeName))                                            {                                                app.modules.Remove(removeName);                                                }                                                   break;                                               case "add":                                            XmlAttribute en = n.Attributes["enabled"];                                            if(en != null && en.Value == "false")                                                continue;                                                                        XmlAttribute nameAtt = n.Attributes["name"];                                            XmlAttribute typeAtt = n.Attributes["type"];                                                   string name = nameAtt == null ? null : nameAtt.Value;                                                   string itype = typeAtt == null ? null : typeAtt.Value;                                                         if(Globals.IsNullorEmpty(name))                                            {                                                EventLogs.Warn(string.Format("A CSModule could not be loaded. The name was not defined. Type {0}", itype), "CSModules", 654, CSContext.Current.SettingsID);                                                continue;                                            }                                            if(Globals.IsNullorEmpty(itype))                                            {                                                EventLogs.Warn(string.Format("A CSModule ({0}) could not be loaded. No type was defined", name), "CSModules", 655, CSContext.Current.SettingsID);                                                continue;                                            }                                                   Type type = Type.GetType(itype);                                             if(type == null)                                            {                                                EventLogs.Warn(string.Format("A CSModule ({0}) could not be loaded. The type {1} does not exist", name,itype), "CSModules", 656, CSContext.Current.SettingsID);                                                continue;                                            }                                                     ICSModule mod = Activator.CreateInstance(type) as ICSModule;                                                   if(mod == null)                                                   {                                                EventLogs.Warn(string.Format("A CSModule ({0}) could not be loaded. The type {1} could not be instantiated", name,itype), "CSModules", 657, CSContext.Current.SettingsID);                                                continue;                                            }                                                    mod.Init(app, n);                                                    app.modules.Add(name,mod);                                                     break;                                           }                                     }                                 }                            }                            CacheDependency dep = new CacheDependency(null, new string[]{CSConfiguration.CacheKey});                            CSCache.Max(key, app,dep);                       }                                           }              }              return app;         }以上代碼通過分析"CommunityServer/CSModules"來載入需要監聽事件的模組(CSModule)                                                    ICSModule mod = Activator.CreateInstance(type) as ICSModule;這裡執行個體化ICSModule利用的是反射。通過此語句 還初始化模組,參與監聽時間。監聽事件 採用的是Add remove形式,允許事件廣播機制在獲得CSModule的執行個體後,馬上調用了其Init函數,這類函數主要是攜帶一個當前CSApplication的執行個體,並攜帶CommunityServer/CSModules配置當前節點的XML節點對象。通常的Inti函數應當通過如下類似代碼進行事件的掛接:public void Init(CSApplication csa, XmlNode node)         {              csa.UserKnown +=new CSUserEventHandler(csa_UserKnown);         }也就是通知CSApplication,該模組會接獲其中的事件。那麼再回到CSApplication 如何管理這些事件並進行分發的呢?在Init函數內部使用 += 來監聽事件的時候,此時會將監聽回呼函數儲存:public event CSUserEventHandler UserKnown         {              add{Events.AddHandler(EventUserKnown, value);}              remove{Events.RemoveHandler(EventUserKnown, value);}         }此時通過add remove 將回呼函數控制代碼儲存到雜湊表中,這樣就允許一個事件多個回呼函數。這樣,大家可看到在CS中,事件流是通過CSApplication執行個體來匯聚,通過其中的事件機制分發到在Init函數中註冊的多個Module,這樣的分發路徑就是: 事件來源 ---》CSApplication執行個體 –》 CSModule1                                          |                                          ------------》CSModule2|-----》CSModule3 。。。。。  這樣設計的好處呢?1、 事件的產生與事件的處理是分離的。2、 可以做到事件的廣播,多個監聽器都可以處理事件;而且這種處理可以通過設定檔來實現。做到,“輕編程重配置”,還做到松耦合。

新增一個事件,有一定的布局結構參考。有利於系統的擴充擴充。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.