你的位置:首页 > ASP.net教程

[ASP.net教程].NET本质论(4)应用程序对象HttpApplication


    当HttpContext对象创建之后,HttpRuntime将随后创建一个用于处理请求的对象,这个对象的类型为HttpApplication.
     在ASP.NET内部,HttpRuntime管理一个定义在System.Web命名空间下的HttpApplicationFactory类的实例,HttpApplicationFactory通过工厂模式管理HttpApplication对象,在HttpApplicationFactory内部维护了一个HttpApplication对象池,使得被创建的HttpApplication对象可以被重复使用,但是,每一个HttpApplication对象每一次仅仅用于处理一个请求,这样,对于ASP.NET程序员来说,也就不需要考虑HttpApplication中多个请求并发的处理问题了。
 在实际的请求处理过程中,我们还需要进行大量的工作,例如,检查当前的请求是由哪一个用户发起的,以此我们就可以针对不同的用户进行不同的处理,或者根据用户来决定是否对用户的请求进行处理,对于没有权限的用户返回一个缺少相应权限的回应等。如果我们在一个方法中来完成这些任务,显然会造成方法的过度臃肿。在HttpApplication中,利用.NET中的事件机制,通过在处理过程中依次发出的多个事件,将这个处理过程分解为多个步骤,这个处理机制通常我们称为处理管道,下面我们将会详细讨论处理管道的内在机制和HttpApplication的多个事件。
    1.处理管道
     所谓的处理管道,就是处理复杂问题的时候,将处理的过程分解为多个处理步骤,我们将这种经过多个步骤的处理方式称为处理管道。在.NET中,借助于事件的强大威力,我们可以通过处理管道将复杂的处理步骤封装起来,通过事件将处理过程 的多个步骤给程序员以便于程序员对管理管道进行扩展。如下图概述了HttpApplication处理管道的工作过程。


     对于一个管道来说,它往往要暴露出大量的事件,通过这些事件,提供程序员的扩展机制。但是,对于一具有着众多事件的类来说,定义大量的事件意味着创建对象的时候需要付出创建事件的成本,因为在.NET中,所谓的事件就是一个受限制的委托成员,定义多个事件,意味着在创建的对象中将会需要更多的存储空间。针对这个问题,在System.ComponentModel.Component类中,提供了处理多个事件的基础:Events属性,它的类型为System.ComponentModel.EventHandlerList,这是一个线性的字典,当需要事件的时候, 就通过key将事件保存到集合中,没有对应的事件,就不会付出创建事件的成本,这样,通过EventHandlerList可以在一个集合中管理多个事件对象,节省对象占用的空间,它的主要成员如下:

 

 

在使用的时候,首先从Component派生一个类,这个类将继承Component的Events集合属性。对于这个派生类所需要定义的每一个类,这个类将继承Component的Event集合属性。对于这个派生类所需要定义的每一个事件,在类中定义一个对应的作为Key的对象,以后,通过这个Key对象来访问由Events集合管理的事件。
 程序员也可以自己在类中定义一个类似的字典来完成这个任务,并不一定要从Component类中派生。如下

 

 

 public class ProcessPipeline : System.ComponentModel.Component  {    #region    private static readonly object startEvent = new object();    private static readonly object preProcessEvent = new object();    private static readonly object postProcessEvent = new object();    private static readonly object endEvent = new object();    #endregion    #region    public event EventHandler StartProcess    {      add { this.Events.AddHandler(startEvent, value); }      remove { this.Events.RemoveHandler(startEvent, value); }    }    public event EventHandler PreProcess    {      add { this.Events.AddHandler(preProcessEvent, value); }      remove { this.Events.RemoveHandler(preProcessEvent, value); }    }    public event EventHandler PostProcess    {      add { this.Events.AddHandler(postProcessEvent, value); }      remove { this.Events.RemoveHandler(postProcessEvent, value); }    }    public event EventHandler EndProcess    {      add { this.Events.AddHandler(endEvent, value); }      remove { this.Events.RemoveHandler(endEvent, value); }    }    #endregion    #region    protected void OnStartProcess(EventArgs e)    {      if (this.Events[startEvent] != null)      {        (this.Events[startEvent] as EventHandler)(this, e);      }    }    protected void OnPreProcess(EventArgs e)    {      if (this.Events[preProcessEvent] != null)      {        (this.Events[preProcessEvent] as EventHandler)(this, e);      }    }    protected void OnPostProcess(EventArgs e)    {      if (this.Events[postProcessEvent] != null)      {        (this.Events[postProcessEvent] as EventHandler)(this, e);      }    }    protected void OnEndProcess(EventArgs e)    {      if (this.Events[endEvent] != null)      {        (this.Events[endEvent] as EventHandler)(this, e);      }    }    #endregion    public void Process()    {      Console.WriteLine("开始处理");      this.OnStartProcess(EventArgs.Empty);      Console.WriteLine("准备处理");      this.OnPreProcess(EventArgs.Empty);      Console.WriteLine("下在处理中。。。");      this.OnPostProcess(EventArgs.Empty);      Console.WriteLine("处理结束");      this.OnEndProcess(EventArgs.Empty);    }  }

 

 

 

 

namespace 自定义事件管道{  class Program  {    static void Main(string[] args)    {      ProcessPipeline process = new ProcessPipeline();      process.StartProcess        += new EventHandler(process_StartProcess);      process.StartProcess        += new EventHandler(process_StartProcess1);      process.StartProcess        -= new EventHandler(process_StartProcess);      process.PreProcess        += new EventHandler(process_PreProcess);      process.PostProcess        += new EventHandler(process_PostProcess);      process.EndProcess        += new EventHandler(process_EndProcess);      process.Process();      Console.ReadLine();    }    static void process_StartProcess(object sender, EventArgs e)    {      Console.WriteLine("开始处理的事件中的处理。。。");    }    static void process_StartProcess1(object sender,EventArgs e)    {      Console.WriteLine("开始处理的事件前的事件中的处理1");    }    static void process_PreProcess(object sender, EventArgs e)    {      Console.WriteLine("处理前的事件中的处理。。。");    }    static void process_PostProcess(object sender, EventArgs e)    {      Console.WriteLine("正在处理的事件中处理中。。。。");    }    static void process_EndProcess(object sender, EventArgs e)    {      Console.WriteLine("处理完成的事件处理。。。");    }  }}

 在ProcessPipeline类中,定义了4个事件,首先需要注意的是在类中并没有定义4个实际的委托成员来对应事件,通过从Component派生,实际上从基类继承了一个EventHandlerList类型的成员,通过将事件以属性的形式来定义,并映射到EventHandlerList中不管在类中定义了多少个事件,在创建的对象实例中只需要这样一个EventHandlerList的对象来保存事件响应的委托对象。
其次,在Process方法中,模拟了处理的过程,在处理的过程中,通过调用触发事件的On开头的方法,以事件的形式将处理的步骤暴露给程序员。
使用这个类的时候,对于程序员关心的处理事件,可以通过注册事件处理方法到相应的事件上,在ProcessPipeline进行处理的过程中,相应的事件处理方法会被调用。




瑞士旅游几月份最好瑞士旅游怎么样几月去瑞士旅游最便宜深圳到加拿大旅游深圳去加拿大旅游报价内蒙古4A级景区克什克腾世界地质公园 不可不吃的内蒙古特色美食 中国宁夏银川4A级景区华夏西部影视城 内蒙古琵琶一曲弹至今 昭君千古墓犹新 富华游乐园有吃饭的地方吗?潍坊富华游乐园森林餐厅怎么样? 潍坊火车站到富华游乐园打车多少钱?潍坊火车站到富华游乐园坐几路公交直达? 杭州汽车站到浮盖山峡谷漂流坐车多长时间?杭州汽车站到浮盖山峡谷漂流怎么坐车? 江山到浮盖山峡谷漂流班车时刻表?江山到浮盖山峡谷漂流怎么坐车? 麦里浩径路线图美图欣赏 香港麦里浩径徒步美景 香港长洲美景欣赏 香港长洲交通路线介绍 清明游香港南丫岛美图分享 2015香港南丫岛景点图片分享 香港迪士尼2015年游玩攻略图片 2015带你游迪士尼乐园 迪拜十大疯狂建筑有哪些?哪些名气较大? 泰国线路哪个好,如何选择泰国旅游线路? 泰国什么化妆品便宜? 迪拜为什么这么有钱? STM1061N19WX6F Datasheet STM1061N19WX6F Datasheet L9950 Datasheet L9950 Datasheet L9950TR Datasheet L9950TR Datasheet 黑龙江出发 香港游 黑龙江出发 香港游 黑龙江出发 香港游 宿迁出发香港旅游 宿迁出发香港旅游 宿迁出发香港旅游 丽水出发香港游 丽水出发香港游 丽水出发香港游