MVC系列(5) Http Pipeline详细分析(下)2015-01-08接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件,比如如下代码:
public class Test : IHttpModule{public void Init(HttpApplication context){context.BeginRequest += new EventHandler(context_BeginRequest);context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);}void context_AuthenticateRequest(object sender, EventArgs e){throw new NotImplementedException();}void context_BeginRequest(object sender, EventArgs e){throw new NotImplementedException();}}然后添加的代码,在Pipeline里执行的时候就会把这些事件给执行了,那么如何执行并且按照什么顺序执行的呢? 在了解这些之前,我们先看看这些事件是如何在HttpApplication里暴露出来了,添加事件存放在何处的呢?阅读HttpApplication 的源码,我们可以看到,所有的事件都是按照如下的形式暴露的,选择其中两个看一下:
/// <devdoc><para>[To be supplied.]</para></devdoc> public event EventHandler BeginRequest {add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }}/// <devdoc><para>[To be supplied.]</para></devdoc> public event EventHandler AuthenticateRequest {add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); } remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }}可以发现,所有的事件都是调用AddSyncEventHookup方法添加进去的,其中第一个参数是以Event+事件名称的值,这个值是如何得来的,我们找到声明的代码:
private static readonly object EventDisposed = new object();private static readonly object EventErrorRecorded = new object();private static readonly object EventPreSendRequestHeaders = new object(); private static readonly object EventPreSendRequestContent = new object(); private static readonly object EventBeginRequest = new object(); private static readonly object EventAuthenticateRequest = new object();private static readonly object EventDefaultAuthentication = new object(); private static readonly object EventPostAuthenticateRequest = new object();private static readonly object EventAuthorizeRequest = new object();private static readonly object EventPostAuthorizeRequest = new object();private static readonly object EventResolveRequestCache = new object(); private static readonly object EventPostResolveRequestCache = new object();private static readonly object EventMapRequestHandler = new object(); private static readonly object EventPostMapRequestHandler = new object(); private static readonly object EventAcquireRequestState = new object();private static readonly object EventPostAcquireRequestState = new object(); private static readonly object EventPreRequestHandlerExecute = new object();private static readonly object EventPostRequestHandlerExecute = new object();private static readonly object EventReleaseRequestState = new object();private static readonly object EventPostReleaseRequestState = new object(); private static readonly object EventUpdateRequestCache = new object();private static readonly object EventPostUpdateRequestCache = new object(); private static readonly object EventLogRequest = new object(); private static readonly object EventPostLogRequest = new object();private static readonly object EventEndRequest = new object();
再结合add和remove方法,可以大胆猜想,这些值应该是作为key值用的,我们先看完第2个参数,再来验证我们的猜想,第2个参数是枚举类型 RequestNotification,这里我们再猜想一下,所有的事件都应该放在统一的地方,然后用这个枚举来区分。让我们先看看这个枚举类的代码:
[Flags]public enum RequestNotification{BeginRequest = 1,AuthenticateRequest = 2,AuthorizeRequest = 4,ResolveRequestCache = 8,MapRequestHandler = 16,AcquireRequestState = 32,PreExecuteRequestHandler = 64,ExecuteRequestHandler = 128,ReleaseRequestState = 256,UpdateRequestCache = 512,LogRequest = 1024,EndRequest = 2048,SendResponse = 536870912,}发现什么了没有?虽然使用了Flags标记来记录以便进行异或查询,但是这里的枚举类型好像少了一些吧,仔细对照代码发现所有以Post开头的事件都没出现在这个枚举类里,为什么呢?那这些事件是如何声明的?回到HttpApplication类来继续查看代码,
/// <devdoc><para>[To be supplied.]</para></devdoc>public event EventHandler PostAuthenticateRequest {add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); } remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }}