最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅。
先看下HttpApplication 对象的创建过程
从IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);这里看出,HttpApplication 实例 是通过HttpApplicationFactory创建出来的,但它内部又是怎样操作的呢?
1、在theApplicationFactory.EnsureInited();方法中确定创建的HttpApplication类的类型,首先从网站中获取global.asax文件,该文件继承自HttpApplication类,如果网站中没有添加该文件,则返回它本身(也是父类)的HttpApplication类类型,如果存在global.asax文件,则返回子类类型的HttpApplication;
2、在 _theApplicationFactory.EnsureAppStartCalled(context);方法中确保global.asax中的start方法被调用,该方法只在网站第一被访问时执行,也就是每一个浏览器第一次访问网站是执行该方法,只执行一次,浏览过程中不会再执行。
3、在theApplicationFactory.GetNormalApplicationInstance(context);方法内通过对象池(将HttpApplication对象插入到一个栈的数据结构中)的技术创建一个HttpApplication实例,如果池内没有现成的实例对象,则通过反射将1中的HttpApplication类的类型传入CreateNonPublicInstance(type, null);方法中,然后创建出一个HttpApplication实例。
至此HttpApplication实例已创建完成。
接着调用application.InitInternal(context, this._state, this._eventHandlerMethods);方法创建出过滤的对象,其中context是一个httpcontext对象:
调用方法 this.InitModules();初始化HttpModule集合。内部又是怎么实现的呢?
1、调用内部方法:this._moduleCollection = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();通过读取网站的配置文件 this._modualEntry = new ModulesEntry(this.Name, this.Type, _propType.Name, this);将modules中所有节点中对应的类型加入到集合中
HttpModuleCollection modules = new HttpModuleCollection();
foreach (HttpModuleAction action in this.Modules)
{
modules.AddModule(action.Entry.ModuleName, action.Entry.Create());
}
modules.AddModule("DefaultAuthentication", new DefaultAuthenticationModule());
return modules;
然后返回modules。
2、在 this.InitModulesCommon();方法中 遍历modules中的每一个对象,并调用它的Init方法,在方法中可以注册HttpApplication处理管道中的19个事件的任意方法。
int count = this._moduleCollection.Count;
for (int i = 0; i < count; i++) {
this._currentModuleCollectionKey = this._moduleCollection.GetKey(i);
this._moduleCollection[i].Init(this);
}
那什么时候执行过滤中的方法呢?
回到前面,此时HttpApplication对象已经创建完成,并且在 HttpApplicationFactory.GetApplicationInstance(context);方法内部已经创建好了httpmodules对象的集合,也注册了相应的处理事件的方法。接下来在调用applicationInstance.ProcessRequest(context);处理方法时,当它处理管道中事件,将会调用相应的httpmodule中的方法,因为她们在创建HttpApplication对象实例的时候已经注册好了。
不知道总结的对不对,希望有高人指正。