博客园 - uGoer - Community Server专题六:Delegates & Events

来源:百度文库 编辑:神马文学网 时间:2024/04/28 12:42:48
Community Server专题六:Delegates & Events
对于CS的分析你可以能会从页面开始,其实那并不是一个很好的方法,因为CS采用了MasterPage和内建的Theme与Skins,页面一层嵌套一层,如果你对CS页面执行机制不了解,或者你是初学者,这个时候可能就会碰壁,接着就放弃了对CS更深入的了解。我希望我的专题能从CS的运行过程开始一步一步地讲解,同时把ASP.NET的运行机理也表述出来,因此学习了解CS的过程就是对ASP.NET深入了解得过程。当然,我个人的开发经验与水平也是有限的,如果在专题中表述有问题,或者有疑问可以直接在文章的评论中直接指出,我将万分感谢你。
在分析CSHttpModule.cs的时候,你会看到这样两句代码:
CSEvents.UserKnown(csContext.User);
CSEvents.CSException(csException);
其实短短两行代码后面隐藏了Delegates与Events的大量运用,CS也通过这样的运用实现了一种模块化的处理机制,即CSModules。
打开CommunityServerWeb项目下的communityserver.config文件,这是CS的配置文件(与Web.config不同,communityserver.config主要配置的是CS内部的一些运行机制,而Web.config主要配置的是与Asp.net的交互)。找到文件中的这段:


              

              

        

              

              

              

              

              

              

              



              

              

              

              

              

              

              

              

              

              

         



我们拿出其中的一个来分析运行过程,例:

这是CS中异常处理的模块,当发生异常的时候该模块将调用一个RedirectToMessage方法,提示一个友好的错误界面,告诉请求的用户有错误发生。那么CS系统是如何在发生错误的时候自动调用RedirectToMessage方法转向另外一个页面提示友好错误的呢?先打开CommunityServerComponents项目下Components文件夹中的CSApplication.cs
using System;

using System.Collections;

using System.ComponentModel;

using System.Web.Caching;

using System.Xml;

using CommunityServer.Configuration;



namespace CommunityServer.Components

{



     Delegates#region Delegates

     //Do we want one single delegate or a custom one for each type

     //public delegate void CSEventHandler(object sender, CSEventArgs e);

     public delegate void CSUserEventHandler(User user, CSEventArgs e);

     public delegate void CSPostEventHandler(Post post, CSEventArgs e);

     public delegate void CSSectionEventHandler(Section section, CSEventArgs e);

     public delegate void CSGroupEventHandler(Group group, CSEventArgs e);

     public delegate void CSExceptionHandler(CSException csEx, CSEventArgs e);

     #endregion



     /**//// 

     /// Summary description for CSApplication.

     /// 


     public class CSApplication

     {

         private members#region private members

         private EventHandlerList Events = new EventHandlerList();

         private static readonly object sync = new object();

         private Hashtable modules = new Hashtable();

         #endregion



         Event Keys (static)#region Event Keys (static)

         private static object EventAuthorizePost = new object();

         private static object EventPrePostUpdate = new object();

         private static object EventPreProcessPost = new object();

         private static object EventPostPostUpdate = new object();

         private static object EventRatePost = new object();

         //private static object EventPreRenderPost = new object();



         private static object EventPreUserUpdate = new object();

         private static object EventPostUserUpdate = new object();

         private static object EventUserRemove = new object();

         private static object EventUserKnown = new object();

         private static object EventUserValidated = new object();



         private static object EventPreSectionUpdate = new object();

         private static object EventPostSectionUpdate = new object();



         private static object EventPreSectionGroupUpdate = new object();

         private static object EventPostSectionGroupUpdate = new object();



         private static object EventUnhandledException = new object();

         #endregion



         cnstr#region cnstr

         private CSApplication()

         {

         }



         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":

                                                   app.modules.Remove(n.Attributes["name"].Value);

                                                   break;

                                               case "add":



                                                   string name = n.Attributes["name"].Value;

                                                   string itype = n.Attributes["type"].Value;



                                                   Type type = Type.GetType(itype);



                                                   if(type == null)

                                                        throw new Exception(itype + " does not exist");



                                                   ICSModule mod = Activator.CreateInstance(type) as ICSModule;



                                                   if(mod == null)

                                                        throw new Exception(itype + " does not implement ICSModule or is not configured correctly");



                                                   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;

         }

         #endregion



         Post Events#region Post Events



         Execute Events#region Execute Events



         internal void ExecuteAuthorizePost()

         {

              ExecuteUserEvent(EventAuthorizePost,CSContext.Current.User);

         }



         internal void ExecutePrePostEvents(Post post, ObjectState state, ApplicationType appType)

         {

              ExecutePostEvent(EventPreProcessPost,post,state,appType);

         }



         internal void ExecutePrePostUpdateEvents(Post post, ObjectState state, ApplicationType appType)

         {

              ExecutePostEvent(EventPrePostUpdate,post,state,appType);

         }



         internal void ExecutePostPostUpdateEvents(Post post, ObjectState state, ApplicationType appType)

         {

              ExecutePostEvent(EventPostPostUpdate,post,state,appType);

         }



         internal void ExecuteRatePostEvents(Post post, ApplicationType appType)

         {

              ExecutePostEvent(EventRatePost,post,ObjectState.None,appType);

         }



//       internal void ExecutePrePostRender(Post post, ApplicationType appType)

//       {

//            ExecutePostEvent(EventPreRenderPost,post,ObjectState.None,appType);

//       }



         protected void ExecutePostEvent(object EventKey, Post post,ObjectState state, ApplicationType appType)

         {

              CSPostEventHandler handler = Events[EventKey] as CSPostEventHandler;

              if (handler != null)

              {

                   handler(post, new CSEventArgs(state,appType));

              }

         }



         #endregion



         Events#region Events

         /**//// 

         /// Event raised before a user accesses a page which can be used to create content

         /// 


         public event CSUserEventHandler AuthorizePost

         {

              add{Events.AddHandler(EventAuthorizePost, value);}

              remove{Events.RemoveHandler(EventAuthorizePost, value);}

         }



         /**//// 

         /// Event raised before any post processing takes place

         /// 


         public event CSPostEventHandler PreProcessPost

         {

              add{Events.AddHandler(EventPreProcessPost, value);}

              remove{Events.RemoveHandler(EventPreProcessPost, value);}

         }



         /**//// 

         /// Fires after PreProcessPost but before the post change is commited to the datastore

         /// 


         public event CSPostEventHandler PrePostUpdate

         {

              add{Events.AddHandler(EventPrePostUpdate, value);}

360docimg_501_              remove360docimg_502_{Events.RemoveHandler(EventPrePostUpdate, value);}
360docimg_503_
360docimg_504_         }
360docimg_505_
360docimg_506_
360docimg_507_
360docimg_508_360docimg_509_         /**//// 
360docimg_510_
360docimg_511_         /// Fires after a post change is commited to the datastore
360docimg_512_
360docimg_513_         /// 

360docimg_514_
360docimg_515_         public event CSPostEventHandler PostPostUpdate
360docimg_516_
360docimg_517_360docimg_518_         360docimg_519_{
360docimg_520_
360docimg_521_360docimg_522_              add360docimg_523_{Events.AddHandler(EventPostPostUpdate, value);}
360docimg_524_
360docimg_525_360docimg_526_              remove360docimg_527_{Events.RemoveHandler(EventPostPostUpdate, value);}
360docimg_528_
360docimg_529_         }
360docimg_530_
360docimg_531_
360docimg_532_
360docimg_533_360docimg_534_         /**//// 
360docimg_535_
360docimg_536_         /// Fires after a Post or Thread is rated
360docimg_537_
360docimg_538_         /// 

360docimg_539_
360docimg_540_         public event CSPostEventHandler RatePost
360docimg_541_
360docimg_542_360docimg_543_         360docimg_544_{
360docimg_545_
360docimg_546_360docimg_547_              add360docimg_548_{Events.AddHandler(EventRatePost, value);}
360docimg_549_
360docimg_550_360docimg_551_              remove360docimg_552_{Events.RemoveHandler(EventRatePost, value);}
360docimg_553_
360docimg_554_         }
360docimg_555_
360docimg_556_
360docimg_557_
360docimg_558_//       /// 
360docimg_559_
360docimg_560_//       /// Event raised before an individual post is rendered
360docimg_561_
360docimg_562_//       /// 

360docimg_563_
360docimg_564_//       public event CSPostEventHandler PreRenderPost
360docimg_565_
360docimg_566_//       {
360docimg_567_
360docimg_568_//            add{Events.AddHandler(EventPreRenderPost, value);}
360docimg_569_
360docimg_570_//            remove{Events.RemoveHandler(EventPreRenderPost, value);}
360docimg_571_
360docimg_572_//       }
360docimg_573_
360docimg_574_
360docimg_575_
360docimg_576_         #endregion
360docimg_577_
360docimg_578_
360docimg_579_
360docimg_580_         #endregion
360docimg_581_
360docimg_582_
360docimg_583_
360docimg_584_360docimg_585_         User Events#region User Events
360docimg_586_
360docimg_587_
360docimg_588_
360docimg_589_360docimg_590_         Execute Events#region Execute Events
360docimg_591_
360docimg_592_
360docimg_593_
360docimg_594_         internal void ExecuteUserValidated(User user)
360docimg_595_
360docimg_596_360docimg_597_         360docimg_598_{
360docimg_599_
360docimg_600_              ExecuteUserEvent(EventUserValidated,user);
360docimg_601_
360docimg_602_         }
360docimg_603_
360docimg_604_
360docimg_605_
360docimg_606_         internal void ExecuteUserKnown(User user)
360docimg_607_
360docimg_608_360docimg_609_         360docimg_610_{
360docimg_611_
360docimg_612_              ExecuteUserEvent(EventUserKnown,user);
360docimg_613_
360docimg_614_         }
360docimg_615_
360docimg_616_
360docimg_617_
360docimg_618_         internal void ExecutePreUserUpdate(User user, ObjectState state)
360docimg_619_
360docimg_620_360docimg_621_         360docimg_622_{
360docimg_623_
360docimg_624_              ExecuteUserEvent(EventPreUserUpdate,user,state,ApplicationType.Unknown);
360docimg_625_
360docimg_626_         }
360docimg_627_
360docimg_628_
360docimg_629_
360docimg_630_         internal void ExecutePostUserUpdate(User user, ObjectState state)
360docimg_631_
360docimg_632_360docimg_633_         360docimg_634_{
360docimg_635_
360docimg_636_              ExecuteUserEvent(EventPostUserUpdate,user,state,ApplicationType.Unknown);
360docimg_637_
360docimg_638_         }
360docimg_639_
360docimg_640_
360docimg_641_
360docimg_642_         internal void ExecuteUserRemove(User user)
360docimg_643_
360docimg_644_360docimg_645_         360docimg_646_{
360docimg_647_
360docimg_648_              ExecuteUserEvent(EventUserRemove,user,ObjectState.Delete,ApplicationType.Unknown);
360docimg_649_
360docimg_650_         }
360docimg_651_
360docimg_652_
360docimg_653_
360docimg_654_         protected void ExecuteUserEvent(object EventKey, User user)
360docimg_655_
360docimg_656_360docimg_657_         360docimg_658_{
360docimg_659_
360docimg_660_              ExecuteUserEvent(EventKey,user,ObjectState.None,ApplicationType.Unknown);
360docimg_661_
360docimg_662_         }
360docimg_663_
360docimg_664_         protected void ExecuteUserEvent(object EventKey, User user,ObjectState state, ApplicationType appType)
360docimg_665_
360docimg_666_360docimg_667_         360docimg_668_{
360docimg_669_
360docimg_670_              CSUserEventHandler handler = Events[EventKey] as CSUserEventHandler;
360docimg_671_
360docimg_672_              if (handler != null)
360docimg_673_
360docimg_674_360docimg_675_              360docimg_676_{
360docimg_677_
360docimg_678_                   handler(user, new CSEventArgs(state,appType));
360docimg_679_
360docimg_680_              }
360docimg_681_
360docimg_682_         }
360docimg_683_
360docimg_684_
360docimg_685_
360docimg_686_         #endregion
360docimg_687_
360docimg_688_
360docimg_689_
360docimg_690_360docimg_691_         Events#region Events
360docimg_692_
360docimg_693_
360docimg_694_
360docimg_695_360docimg_696_         /**//// 
360docimg_697_
360docimg_698_         /// Fires after a user‘s credentials have been validated.
360docimg_699_
360docimg_700_         /// 

360docimg_701_
360docimg_702_         public event CSUserEventHandler UserValidated
360docimg_703_
360docimg_704_360docimg_705_         360docimg_706_{
360docimg_707_
360docimg_708_360docimg_709_              add360docimg_710_{Events.AddHandler(EventUserValidated, value);}
360docimg_711_
360docimg_712_360docimg_713_              remove360docimg_714_{Events.RemoveHandler(EventUserValidated, value);}
360docimg_715_
360docimg_716_         }
360docimg_717_
360docimg_718_
360docimg_719_
360docimg_720_360docimg_721_         /**//// 
360docimg_722_
360docimg_723_         /// Fires once the current user has been identified. This user may still be anonymous.
360docimg_724_
360docimg_725_         /// 

360docimg_726_
360docimg_727_         public event CSUserEventHandler UserKnown
360docimg_728_
360docimg_729_360docimg_730_         360docimg_731_{
360docimg_732_
360docimg_733_360docimg_734_              add360docimg_735_{Events.AddHandler(EventUserKnown, value);}
360docimg_736_
360docimg_737_360docimg_738_              remove360docimg_739_{Events.RemoveHandler(EventUserKnown, value);}
360docimg_740_
360docimg_741_         }
360docimg_742_
360docimg_743_
360docimg_744_
360docimg_745_360docimg_746_         /**//// 
360docimg_747_
360docimg_748_         /// Fires before a User is saved/updated to the datastore
360docimg_749_
360docimg_750_         /// 

360docimg_751_
360docimg_752_         public event CSUserEventHandler PreUserUpdate
360docimg_753_
360docimg_754_360docimg_755_         360docimg_756_{
360docimg_757_
360docimg_758_360docimg_759_              add360docimg_760_{Events.AddHandler(EventPreUserUpdate, value);}
360docimg_761_
360docimg_762_360docimg_763_              remove360docimg_764_{Events.RemoveHandler(EventPreUserUpdate, value);}
360docimg_765_
360docimg_766_         }
360docimg_767_
360docimg_768_
360docimg_769_
360docimg_770_360docimg_771_         /**//// 
360docimg_772_
360docimg_773_         /// Fires after a User is saved/updated to the datastore
360docimg_774_
360docimg_775_         /// 

360docimg_776_
360docimg_777_         public event CSUserEventHandler PostUserUpdate
360docimg_778_
360docimg_779_360docimg_780_         360docimg_781_{
360docimg_782_
360docimg_783_360docimg_784_              add360docimg_785_{Events.AddHandler(EventPostUserUpdate, value);}
360docimg_786_
360docimg_787_360docimg_788_              remove360docimg_789_{Events.RemoveHandler(EventPostUserUpdate, value);}
360docimg_790_
360docimg_791_         }
360docimg_792_
360docimg_793_
360docimg_794_
360docimg_795_360docimg_796_         /**//// 
360docimg_797_
360docimg_798_         /// Fires before a User is removed from the datastore.
360docimg_799_
360docimg_800_         /// 

360docimg_801_
360docimg_802_         public event CSUserEventHandler UserRemove
360docimg_803_
360docimg_804_360docimg_805_         360docimg_806_{
360docimg_807_
360docimg_808_360docimg_809_              add360docimg_810_{Events.AddHandler(EventUserRemove, value);}
360docimg_811_
360docimg_812_360docimg_813_              remove360docimg_814_{Events.RemoveHandler(EventUserRemove, value);}
360docimg_815_
360docimg_816_         }
360docimg_817_
360docimg_818_
360docimg_819_
360docimg_820_         #endregion
360docimg_821_
360docimg_822_
360docimg_823_
360docimg_824_         #endregion
360docimg_825_
360docimg_826_
360docimg_827_
360docimg_828_360docimg_829_         Section Events#region Section Events
360docimg_830_
360docimg_831_
360docimg_832_
360docimg_833_         internal void ExecutePreSectionUpdate(Section section, ObjectState state, ApplicationType appType)
360docimg_834_
360docimg_835_360docimg_836_         360docimg_837_{
360docimg_838_
360docimg_839_              CSSectionEventHandler handler = Events[EventPreSectionUpdate] as CSSectionEventHandler;
360docimg_840_
360docimg_841_              if (handler != null)
360docimg_842_
360docimg_843_360docimg_844_              360docimg_845_{
360docimg_846_
360docimg_847_                   handler(section, new CSEventArgs(state,appType));
360docimg_848_
360docimg_849_              }
360docimg_850_
360docimg_851_         }
360docimg_852_
360docimg_853_
360docimg_854_
360docimg_855_         internal void ExecutePostSectionUpdate(Section section, ObjectState state, ApplicationType appType)
360docimg_856_
360docimg_857_360docimg_858_         360docimg_859_{
360docimg_860_
360docimg_861_              CSSectionEventHandler handler = Events[EventPostSectionUpdate] as CSSectionEventHandler;
360docimg_862_
360docimg_863_              if (handler != null)
360docimg_864_
360docimg_865_360docimg_866_              360docimg_867_{
360docimg_868_
360docimg_869_                   handler(section, new CSEventArgs(state,appType));
360docimg_870_
360docimg_871_              }
360docimg_872_
360docimg_873_         }
360docimg_874_
360docimg_875_
360docimg_876_
360docimg_877_
360docimg_878_
360docimg_879_360docimg_880_         /**//// 
360docimg_881_
360docimg_882_         /// Event raised before a section change is committed to the datastore (create/update)
360docimg_883_
360docimg_884_         /// 

360docimg_885_
360docimg_886_         public event CSSectionEventHandler PreSectionUpdate
360docimg_887_
360docimg_888_360docimg_889_         360docimg_890_{
360docimg_891_
360docimg_892_360docimg_893_              add360docimg_894_{Events.AddHandler(EventPreSectionUpdate, value);}
360docimg_895_
360docimg_896_360docimg_897_              remove360docimg_898_{Events.RemoveHandler(EventPreSectionUpdate, value);}
360docimg_899_
360docimg_900_         }
360docimg_901_
360docimg_902_
360docimg_903_
360docimg_904_
360docimg_905_
360docimg_906_360docimg_907_         /**//// 
360docimg_908_
360docimg_909_         /// Event raised after a section chage is committed to the data store
360docimg_910_
360docimg_911_         /// 

360docimg_912_
360docimg_913_         public event CSSectionEventHandler PostSectionUpdate
360docimg_914_
360docimg_915_360docimg_916_         360docimg_917_{
360docimg_918_
360docimg_919_360docimg_920_              add360docimg_921_{Events.AddHandler(EventPostSectionUpdate, value);}
360docimg_922_
360docimg_923_360docimg_924_              remove360docimg_925_{Events.RemoveHandler(EventPostSectionUpdate, value);}
360docimg_926_
360docimg_927_         }
360docimg_928_
360docimg_929_
360docimg_930_
360docimg_931_         #endregion
360docimg_932_
360docimg_933_
360docimg_934_
360docimg_935_360docimg_936_         Group Events#region Group Events
360docimg_937_
360docimg_938_
360docimg_939_
360docimg_940_         internal void ExecutePreSectionGroupUpdate(Group group, ObjectState state, ApplicationType appType)
360docimg_941_
360docimg_942_360docimg_943_         360docimg_944_{
360docimg_945_
360docimg_946_              CSGroupEventHandler handler = Events[EventPreSectionGroupUpdate] as CSGroupEventHandler;
360docimg_947_
360docimg_948_              if (handler != null)
360docimg_949_
360docimg_950_360docimg_951_              360docimg_952_{
360docimg_953_
360docimg_954_                   handler(group, new CSEventArgs(state,appType));
360docimg_955_
360docimg_956_              }
360docimg_957_
360docimg_958_         }
360docimg_959_
360docimg_960_
360docimg_961_
360docimg_962_         internal void ExecutePostSectionGroupUpdate(Group group, ObjectState state, ApplicationType appType)
360docimg_963_
360docimg_964_360docimg_965_         360docimg_966_{
360docimg_967_
360docimg_968_              CSGroupEventHandler handler = Events[EventPostSectionGroupUpdate] as CSGroupEventHandler;
360docimg_969_
360docimg_970_              if (handler != null)
360docimg_971_
360docimg_972_360docimg_973_              360docimg_974_{
360docimg_975_
360docimg_976_                   handler(group, new CSEventArgs(state,appType));
360docimg_977_
360docimg_978_              }
360docimg_979_
360docimg_980_         }
360docimg_981_
360docimg_982_
360docimg_983_
360docimg_984_360docimg_985_         /**//// 
360docimg_986_
360docimg_987_         /// Event raised before a group chage is committed to the datastore (create/update)
360docimg_988_
360docimg_989_         /// 

360docimg_990_
360docimg_991_         public event CSGroupEventHandler PreSectionGroupUpdate
360docimg_992_
360docimg_993_360docimg_994_         360docimg_995_{
360docimg_996_
360docimg_997_360docimg_998_              add360docimg_999_{Events.AddHandler(EventPreSectionGroupUpdate, value);}
360docimg_1000_
360docimg_1001_360docimg_1002_              remove360docimg_1003_{Events.RemoveHandler(EventPreSectionGroupUpdate, value);}
360docimg_1004_
360docimg_1005_         }
360docimg_1006_
360docimg_1007_
360docimg_1008_
360docimg_1009_360docimg_1010_         /**//// 
360docimg_1011_
360docimg_1012_         /// Event raised after a group chage is committed to the data store
360docimg_1013_
360docimg_1014_         /// 

360docimg_1015_
360docimg_1016_         public event CSGroupEventHandler PostSectionGroupUpdate
360docimg_1017_
360docimg_1018_360docimg_1019_         360docimg_1020_{
360docimg_1021_
360docimg_1022_360docimg_1023_              add360docimg_1024_{Events.AddHandler(EventPostSectionGroupUpdate, value);}
360docimg_1025_
360docimg_1026_360docimg_1027_              remove360docimg_1028_{Events.RemoveHandler(EventPostSectionGroupUpdate, value);}
360docimg_1029_
360docimg_1030_         }
360docimg_1031_
360docimg_1032_
360docimg_1033_
360docimg_1034_         #endregion
360docimg_1035_
360docimg_1036_
360docimg_1037_
360docimg_1038_360docimg_1039_         Exceptions#region Exceptions
360docimg_1040_
360docimg_1041_360docimg_1042_         /**//// 
360docimg_1043_
360docimg_1044_         /// Event raised before a group chage is committed to the datastore (create/update)
360docimg_1045_
360docimg_1046_         /// 

360docimg_1047_
360docimg_1048_         public event CSExceptionHandler CSException
360docimg_1049_
360docimg_1050_360docimg_1051_         360docimg_1052_{
360docimg_1053_
360docimg_1054_360docimg_1055_              add360docimg_1056_{Events.AddHandler(EventUnhandledException, value);}
360docimg_1057_
360docimg_1058_360docimg_1059_              remove360docimg_1060_{Events.RemoveHandler(EventUnhandledException, value);}
360docimg_1061_
360docimg_1062_         }
360docimg_1063_
360docimg_1064_
360docimg_1065_
360docimg_1066_         internal void ExecuteCSExcetion(CSException csEx)
360docimg_1067_
360docimg_1068_360docimg_1069_         360docimg_1070_{
360docimg_1071_
360docimg_1072_              CSExceptionHandler handler = Events[EventUnhandledException] as CSExceptionHandler;
360docimg_1073_
360docimg_1074_              if (handler != null)
360docimg_1075_
360docimg_1076_360docimg_1077_              360docimg_1078_{
360docimg_1079_
360docimg_1080_                   handler(csEx,new CSEventArgs());
360docimg_1081_
360docimg_1082_              }
360docimg_1083_
360docimg_1084_         }
360docimg_1085_
360docimg_1086_
360docimg_1087_
360docimg_1088_         #endregion
360docimg_1089_
360docimg_1090_
360docimg_1091_
360docimg_1092_     }
360docimg_1093_
360docimg_1094_}
360docimg_1095_
360docimg_1096_
文件太长,我们抓出关键的部分来分析:
360docimg_1097_public delegate void CSExceptionHandler(CSException csEx, CSEventArgs e);
360docimg_1098_
360docimg_1099_
这里先申明一个委托,相当于一个函数指针。在通俗一点理解它就是一个跑腿的,专管传递对象与对象间的调用信息。
接下来:
360docimg_1100_internal static CSApplication Instance()
360docimg_1101_
360docimg_1102_360docimg_1103_         360docimg_1104_{
360docimg_1105_
360docimg_1106_              const string key = "CSApplication";
360docimg_1107_
360docimg_1108_              CSApplication app = CSCache.Get(key) as CSApplication;
360docimg_1109_
360docimg_1110_              if(app == null)
360docimg_1111_
360docimg_1112_360docimg_1113_              360docimg_1114_{
360docimg_1115_
360docimg_1116_                   lock(sync)
360docimg_1117_
360docimg_1118_360docimg_1119_                   360docimg_1120_{
360docimg_1121_
360docimg_1122_                       app = CSCache.Get(key) as CSApplication;
360docimg_1123_
360docimg_1124_                       if(app == null)
360docimg_1125_
360docimg_1126_360docimg_1127_                       360docimg_1128_{
360docimg_1129_
360docimg_1130_                            CSConfiguration config = CSContext.Current.Config;
360docimg_1131_
360docimg_1132_
360docimg_1133_
360docimg_1134_                            XmlNode node = config.GetConfigSection("CommunityServer/CSModules");
360docimg_1135_
360docimg_1136_                            app = new CSApplication();
360docimg_1137_
360docimg_1138_                            if(node != null)
360docimg_1139_
360docimg_1140_360docimg_1141_                            360docimg_1142_{
360docimg_1143_
360docimg_1144_                                 foreach(XmlNode n in node.ChildNodes)
360docimg_1145_
360docimg_1146_360docimg_1147_                                 360docimg_1148_{
360docimg_1149_
360docimg_1150_                                     if(n.NodeType != XmlNodeType.Comment)
360docimg_1151_
360docimg_1152_360docimg_1153_                                     360docimg_1154_{
360docimg_1155_
360docimg_1156_                                          switch(n.Name)
360docimg_1157_
360docimg_1158_360docimg_1159_                                          360docimg_1160_{
360docimg_1161_
360docimg_1162_                                               case "clear":
360docimg_1163_
360docimg_1164_                                                   app.modules.Clear();
360docimg_1165_
360docimg_1166_                                                   break;
360docimg_1167_
360docimg_1168_                                               case "remove":
360docimg_1169_
360docimg_1170_                                                   app.modules.Remove(n.Attributes["name"].Value);
360docimg_1171_
360docimg_1172_                                                   break;
360docimg_1173_
360docimg_1174_                                               case "add":
360docimg_1175_
360docimg_1176_
360docimg_1177_
360docimg_1178_                                                   string name = n.Attributes["name"].Value;
360docimg_1179_
360docimg_1180_                                                   string itype = n.Attributes["type"].Value;
360docimg_1181_
360docimg_1182_
360docimg_1183_
360docimg_1184_                                                   Type type = Type.GetType(itype);
360docimg_1185_
360docimg_1186_
360docimg_1187_
360docimg_1188_                                                   if(type == null)
360docimg_1189_
360docimg_1190_                                                        throw new Exception(itype + " does not exist");
360docimg_1191_
360docimg_1192_
360docimg_1193_
360docimg_1194_                                                   ICSModule mod = Activator.CreateInstance(type) as ICSModule;
360docimg_1195_
360docimg_1196_
360docimg_1197_
360docimg_1198_                                                   if(mod == null)
360docimg_1199_
360docimg_1200_                                                        throw new Exception(itype + " does not implement ICSModule or is not configured correctly");
360docimg_1201_
360docimg_1202_
360docimg_1203_
360docimg_1204_                                                   mod.Init(app, n);
360docimg_1205_
360docimg_1206_                                                   app.modules.Add(name,mod);
360docimg_1207_
360docimg_1208_
360docimg_1209_
360docimg_1210_
360docimg_1211_
360docimg_1212_                                                   break;
360docimg_1213_
360docimg_1214_
360docimg_1215_
360docimg_1216_                                          }
360docimg_1217_
360docimg_1218_                                     }
360docimg_1219_
360docimg_1220_                                 }
360docimg_1221_
360docimg_1222_                            }
360docimg_1223_
360docimg_1224_360docimg_1225_                            CacheDependency dep = new CacheDependency(null, new string[]360docimg_1226_{CSConfiguration.CacheKey});
360docimg_1227_
360docimg_1228_                            CSCache.Max(key, app,dep);
360docimg_1229_
360docimg_1230_                       }
360docimg_1231_
360docimg_1232_
360docimg_1233_
360docimg_1234_
360docimg_1235_
360docimg_1236_                   }
360docimg_1237_
360docimg_1238_              }
360docimg_1239_
360docimg_1240_              return app;
360docimg_1241_
360docimg_1242_         }
360docimg_1243_
360docimg_1244_
这段很重要,通过读取communityserver.config文件的,初始化每个CSModule,注意,初始化后并且调用了这些CSModule中的Init方法。具体看看这些Module中的Init都做了什么,打开CommunityServerComponents项目下的Components文件夹中的CSExceptionModule.cs:
360docimg_1245_using System;
360docimg_1246_
360docimg_1247_using System.Web;
360docimg_1248_
360docimg_1249_
360docimg_1250_
360docimg_1251_namespace CommunityServer.Components
360docimg_1252_
360docimg_1253_360docimg_1254_360docimg_1255_{
360docimg_1256_
360docimg_1257_360docimg_1258_     /**//// 
360docimg_1259_
360docimg_1260_     /// Summary description for CSExceptionModule.
360docimg_1261_
360docimg_1262_     /// 

360docimg_1263_
360docimg_1264_     public class CSExceptionModule : ICSModule
360docimg_1265_
360docimg_1266_360docimg_1267_     360docimg_1268_{
360docimg_1269_
360docimg_1270_         public CSExceptionModule()
360docimg_1271_
360docimg_1272_360docimg_1273_         360docimg_1274_{
360docimg_1275_
360docimg_1276_              //
360docimg_1277_
360docimg_1278_              // TODO: Add constructor logic here
360docimg_1279_
360docimg_1280_              //
360docimg_1281_
360docimg_1282_         }
360docimg_1283_
360docimg_1284_360docimg_1285_          ICSModule Members#region ICSModule Members
360docimg_1286_
360docimg_1287_
360docimg_1288_
360docimg_1289_         public void Init(CSApplication csa, System.Xml.XmlNode node)
360docimg_1290_
360docimg_1291_360docimg_1292_         360docimg_1293_{
360docimg_1294_
360docimg_1295_              csa.CSException +=new CSExceptionHandler(csa_CSException);
360docimg_1296_
360docimg_1297_         }
360docimg_1298_
360docimg_1299_
360docimg_1300_
360docimg_1301_         #endregion
360docimg_1302_
360docimg_1303_
360docimg_1304_
360docimg_1305_         private void csa_CSException(CSException csEx, CSEventArgs e)
360docimg_1306_
360docimg_1307_360docimg_1308_         360docimg_1309_{
360docimg_1310_
360docimg_1311_              CSContext csContext = CSContext.Current;
360docimg_1312_
360docimg_1313_
360docimg_1314_
360docimg_1315_              if (csEx.ExceptionType != CSExceptionType.UnknownError && csContext.IsWebRequest)
360docimg_1316_
360docimg_1317_360docimg_1318_              360docimg_1319_{
360docimg_1320_
360docimg_1321_                   RedirectToMessage(csContext.Context, csEx);
360docimg_1322_
360docimg_1323_              }
360docimg_1324_
360docimg_1325_         }
360docimg_1326_
360docimg_1327_
360docimg_1328_
360docimg_1329_         private static void RedirectToMessage (HttpContext context, CSException exception)
360docimg_1330_
360docimg_1331_360docimg_1332_         360docimg_1333_{
360docimg_1334_
360docimg_1335_
360docimg_1336_
360docimg_1337_              if ((exception.InnerException != null) && ( exception.InnerException is CSException))
360docimg_1338_
360docimg_1339_360docimg_1340_              360docimg_1341_{
360docimg_1342_
360docimg_1343_                   CSException inner = (CSException) exception.InnerException;
360docimg_1344_
360docimg_1345_              }
360docimg_1346_
360docimg_1347_              context.Response.Redirect(Globals.GetSiteUrls().Message( exception.ExceptionType ), true);
360docimg_1348_
360docimg_1349_         }
360docimg_1350_
360docimg_1351_
360docimg_1352_
360docimg_1353_     }
360docimg_1354_
360docimg_1355_}
360docimg_1356_
360docimg_1357_
哈哈,原来在Init方法里把一个CSExceptionHandler委托添加到CSException事件上,这个委托指向csa_CSException方法,还是通俗点说:如果CSException这个事件发生了,CSExceptionHandler这个跑腿的委托就会马上告诉csa_CSException方法要他执行,如果事件没有被激发就什么也不做。
名词: event 关键字使您得以指定当代码中的某些“事件”发生时调用的委托。此委托可以有一个或多个关联的方法,当代码指示该事件已发生时将调用关联的方法。
那么这个CSException又是怎么回事?在哪里定义的?我们回到CSApplication.cs文件中,看样几行:
360docimg_1358_         public event CSExceptionHandler CSException
360docimg_1359_
360docimg_1360_360docimg_1361_         360docimg_1362_{
360docimg_1363_
360docimg_1364_360docimg_1365_              add360docimg_1366_{Events.AddHandler(EventUnhandledException, value);}
360docimg_1367_
360docimg_1368_360docimg_1369_              remove360docimg_1370_{Events.RemoveHandler(EventUnhandledException, value);}
360docimg_1371_
360docimg_1372_     }
360docimg_1373_
这里定义了一个CSException事件,而事件发生的时候只能用CSExceptionHandler这个委托来做跑腿的。其实CS中是把委托都存放在了一个EventHandlerList中,因此此处你可以看到add与remove, 这是访问器的声明,用于添加或移除客户代码中的事件处理程序,这样做的好处是公开大量的事件但不为每个事件分配字段,而是使用EventHandlerList存储这些事件实例。为了理解事件的调用执行过程,我们还必须看几个文件:CSEvents.cs、CSEventArgs.cs:
CSEventArgs.cs存储事件的数据,这个很好理解,它继承自EventArgs。当事件发生时CSEventArgs用来传递事件的信息,这里传递两个值:ObjectState与ApplicationType(可以在Enumerations文件夹下找到这两个枚举的内容)
CSEvents.cs这是对事件调用的一个包装器,看异常处理的包装:
360docimg_1374_         public static void CSException(CSException csEx)
360docimg_1375_
360docimg_1376_360docimg_1377_         360docimg_1378_{
360docimg_1379_
360docimg_1380_              CSApplication.Instance().ExecuteCSExcetion(csEx);
360docimg_1381_
360docimg_1382_          }
360docimg_1383_
这里先调用CSApplication.Instance()方法,实例化一个CSApplication对象,如果你是第一次调用Instance()方法,就实例化所有在中配置的类,并且调用他们的Init方法(在CSModules中配置的这些类,都实现了ICSModule接口,而这个接口要求继承他的类都具备Init方法),执行Init方法的目的就是把委托添加到事件上,使委托指向的方法可以在事件触发的时候被调用。实例化后再调用ExecuteCSExcetion方法并且传递CSException的实例,ExecuteCSExcetion方法如下:
360docimg_1384_         internal void ExecuteCSExcetion(CSException csEx)
360docimg_1385_
360docimg_1386_360docimg_1387_         360docimg_1388_{
360docimg_1389_
360docimg_1390_              CSExceptionHandler handler = Events[EventUnhandledException] as CSExceptionHandler;
360docimg_1391_
360docimg_1392_              if (handler != null)
360docimg_1393_
360docimg_1394_360docimg_1395_              360docimg_1396_{
360docimg_1397_
360docimg_1398_                   handler(csEx,new CSEventArgs());
360docimg_1399_
360docimg_1400_              }
360docimg_1401_
360docimg_1402_         }
360docimg_1403_
先通过对EventHandlerList索引访问,即Events[EventUnhandledException],从列表中找到这个CSExceptionHandler事件,如果不为null就执行它。EventUnhandledException又是什么,其实这只是一个Key,用来标示存储的事件。
有必要总结一下,不然你会被这种调用来调用去的关系搞得一头雾水,
以异常处理为例:
1:在错误发生后,调用Application_OnError方法;
2:在方法的最后调用CSEvents.CSException(csException);
3:进入CSEvents包装器,调用CSApplication.Instance().ExecuteCSExcetion(csEx);
4:执行CSApplication.Instance()方法,如果是第一次执行就根据communityserver.config文件中的配置,把所有的CSModules实例化,并且调用ICSModule接口类中的Init方法,然后缓存这些实例化的类(如果是第二次访问就从缓存中读取)。
5:在实现ICSModule接口的类中,如CSExceptionModule.cs,Init方法是给事件添加委托的过程,这个过程中实现了委托指向的一个或者多个方法与事件进行关联,异常处理的方法csa_CSException(CSException csEx, CSEventArgs e)就是在这里被关联到异常事件上的。
6:经过上面几步后,CS系统接着调用ExecuteCSExcetion方法,在ExecuteCSExcetion方触发了CSException事件
7:CSException事件被触发后,就执行事件中委托所指向的函数,这里是CSExceptionModule.cs文件中的private void csa_CSException(CSException csEx, CSEventArgs e)。
CS如此大量的使用Delegates与Events带来了什么,也许你会认为它这样是把问题复杂化,而且觉得这非常没有必要,完全可以在异常处理的最后调用处理方法即可,何必通过事件来回周转!最后说明一下这样做的重要性:
1:通过事件使调用方法者与方法本身隔离,如在CSHttpModule.cs文件中的Application_OnError方法触发CSEvents.CSException事件,而事件要做些什么处理,需要调用什么方法Application_OnError根本不知道。如果你要改变CSEvents.CSException事件处理方法的结构,甚至十处理方法的名称,Application_OnError也不需要改动,因为他根本不关心具体的实现,它的任务只是触发这个事件。
2:如果你想一个方法调用多个方法,普通的做法就是在方法中一次调用或者在方法中嵌套调用。这样做并不是一个好的设计模式,而事件可以通过委托调用多个委托指向的方法(在异常处理中只指向了一个方法,当然你可以指向任意N个方法),而这种调用也是相互隔离的,被调用的方法并不致到谁调用它,而调用者也不关心它调用谁。
3:模块化,你的代码直接没有非常的多紧密联系,而是通过事件来通知处理方法,在CS中又加入了xml的配置文件,使得这样的模块化更突出,你甚至可以把处理异常的类单独编译在一个dll中。
好处还有很多…
在CS中,对Post内容的不良信息过滤也是通过这样的机制完成的,运行的过程基本一致,只是调用不同的事件处理方法,你可以自己分析。
posted on 2005-09-12 13:21uGoer 阅读(1705)评论(6)  编辑 收藏收藏至365Key 所属分类:5:Community Server专题
360docimg_1404_
博客园 - uGoer - Community Server专题六:Delegates & Events 博客园 - uGoer - Community Server专题一:概述Community Server 博客园 - uGoer - Community Server专题二:体系结构 Community Server专题 [推荐]社区网站源代码Community Server 为 WebSphere Application Server Community Edit... Microsoft Windows 2000 SMTP Service Events (SMTP Server Technical Articles) 使用 WebSphere Application Server Community Edition Server 的 Eclipse 插件 SQL Server专题 Huihoo - IBM WebSphere Application Server Community Edition 初试 删除SQL Server日志 - 无风 - 博客园 为 WebSphere Application Server Community Edition 开发 Spring 应用程序: 第 1 部分:Spring MVC IBM WebSphere 开发者技术期刊: WebSphere Application Server Community Edition 入门 JavaScript Events SQL Server 文件规划 - 文件组 - 陈希章@中国 - 博客园 为SQL Server使用非标准的端口 - 蓉青姚 - 博客园 专题六?修辞手法 平均线&葛兰威尔八大买卖法则 - 7events的日志 - 网易博客 sql server compact 与 sql server 2005 通过远程访问进行数据同步-jeff chow-博客园 【实验室纯水专题】纯水秘笈之独孤九式(六)?密理博中国博客 WebSphere Application Server Community Edition 中的高级管理,第 2 部分: 使用线程池、集群和配置插件 为 WebSphere Application Server Community Edition 开发 Spring 应用程序: 第 2 部分:使用 Spring 进行数据库连接管理 Server Tours & Events whte house