博客园 - 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_
对于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文件的
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()方法,就实例化所有在
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