.Net MVC 里面的核心文件Global.asax运行原理分析
来源:互联网 发布:淘宝确认订单 编辑:程序博客网 时间:2024/06/05 19:48
这个 Global.asax文件是MVC里面的起始文件,它不同于其它文件比如,M层,V层和C层。他是一个独立的可配置的文件。
因为.Net MVC把前后端完全分离,极度抽象的一个框架。或许导致了很多从WebForm转过来的不适应。Global文件就是此类。
它与MVC里面的筛选器,控制器类工程(controllerFactory)的交互式怎么做大的呢?
实际上在System.Web命名空间里面,PipelineRunTime类的InitializeApplication方法会通过HttpApplicationFactory调用GetPipelineApplicationInstance方法创建Global.asax文件类。
app(Global.asax) = HttpApplicationFactory.GetPipelineApplicationInstance(appContext, context); GetPipelineApplicationInstance调用如下: internal static HttpApplication GetPipelineApplicationInstance(IntPtr appContext, HttpContext context) { _theApplicationFactory.EnsureInited(); return _theApplicationFactory.GetSpecialApplicationInstance(appContext, context); }
_theApplicationFactory 是一个全局静态类实例 private static HttpApplicationFactory _theApplicationFactory = new HttpApplicationFactory();实际上就是httpApplicationFactory类工场实例。
EnsureInited代码如下
private void EnsureInited() { if (!this._inited) { HttpApplicationFactory factory = this; lock (factory) { if (!this._inited) { this.Init(); this._inited = true; } } } }
Init代码如下:
private void Init() { if (_customApplication == null) { try { try { this._appFilename = GetApplicationFile(); this.CompileApplication(); } finally { this.SetupChangesMonitor(); } } catch { throw; } } }
CompileApplication代码如下:
private void CompileApplication() { this._theApplicationType = BuildManager.GetGlobalAsaxType(); BuildResultCompiledGlobalAsaxType globalAsaxBuildResult = BuildManager.GetGlobalAsaxBuildResult(); if (globalAsaxBuildResult != null) { if (globalAsaxBuildResult.HasAppOrSessionObjects) { this.GetAppStateByParsingGlobalAsax(); } this._fileDependencies = globalAsaxBuildResult.VirtualPathDependencies; } if (this._state == null) { this._state = new HttpApplicationState(); } this.ReflectOnApplicationType(); }
ReflectOnApplicationType代码如下:
private void ReflectOnApplicationType() { ArrayList list = new ArrayList(); foreach (MethodInfo info in this._theApplicationType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) { if (this.ReflectOnMethodInfoIfItLooksLikeEventHandler(info)) { list.Add(info); } } Type baseType = this._theApplicationType.BaseType; if ((baseType != null) && (baseType != typeof(HttpApplication))) { foreach (MethodInfo info2 in baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (info2.IsPrivate && this.ReflectOnMethodInfoIfItLooksLikeEventHandler(info2)) { list.Add(info2); } } } this._eventHandlerMethods = new MethodInfo[list.Count]; for (int i = 0; i < this._eventHandlerMethods.Length; i++) { this._eventHandlerMethods[i] = (MethodInfo) list[i]; } }
ReflectOnMethodInfoIfItLooksLikeEventHandler代码如下:
private bool ReflectOnMethodInfoIfItLooksLikeEventHandler(MethodInfo m) { if (m.ReturnType != typeof(void)) { return false; } ParameterInfo[] parameters = m.GetParameters(); int length = parameters.Length; if (length != 0) { if (length != 2) { return false; } if (parameters[0].ParameterType != typeof(object)) { return false; } if ((parameters[1].ParameterType != typeof(EventArgs)) && !parameters[1].ParameterType.IsSubclassOf(typeof(EventArgs))) { return false; } } string name = m.Name; int index = name.IndexOf('_'); if ((index <= 0) || (index > (name.Length - 1))) { return false; } if (StringUtil.EqualsIgnoreCase(name, "Application_OnStart") || StringUtil.EqualsIgnoreCase(name, "Application_Start")) { this._onStartMethod = m; this._onStartParamCount = parameters.Length; } else if (StringUtil.EqualsIgnoreCase(name, "Application_OnEnd") || StringUtil.EqualsIgnoreCase(name, "Application_End")) { this._onEndMethod = m; this._onEndParamCount = parameters.Length; } else if (StringUtil.EqualsIgnoreCase(name, "Session_OnEnd") || StringUtil.EqualsIgnoreCase(name, "Session_End")) { this._sessionOnEndMethod = m; this._sessionOnEndParamCount = parameters.Length; } return true; }
ReflectOnMethodInfoIfItLooksLikeEventHandler里面获取到了当前Global.asax方法Application_OnStart
再来看GetPipelineApplicationInstance方法里面调用的第二个方法GetSpecialApplicationInstance。它里面会调用 application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType);创建HtppApplication ,实际上就是Global.asax里面的类MvcApplication。它会调用ProcessSpecialRequest方法反射上面得到的HttpApplication里面的方法Application_start,最后用Invoke调用。
this.InvokeMethodWithAssert(method, paramCount, eventSource, eventArgs); [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.RestrictedMemberAccess)] private void InvokeMethodWithAssert(MethodInfo method, int paramCount, object eventSource, EventArgs eventArgs) { if (paramCount == 0) { method.Invoke(this, new object[0]); } else { object[] parameters = new object[] { eventSource, eventArgs }; method.Invoke(this, parameters); } }
最后进入到Application_start()里面调用MVC的一些前奏,比如配置全局筛选器,创建路由表,注册Area等等。
值得注意的是,这一系列事件都在 进入HTTPModule和HttpHandler之前发生,所以后面等到激活Controller调用ControllerFactory和筛选器递归链的时候,Application_start里面的配置都会起作用。
还有一点需要注意的是,这个Application_start只会在第一次请求加载,后续陆续请求不会再次加载。如果需要重新加载,关掉程序,重新来过,则又会运行到Application_start方法里面。
- .Net MVC 里面的核心文件Global.asax运行原理分析
- ASP.NET MVC中的Global.asax文件
- ASP.NET MVC中的Global.asax文件
- ASP.NET MVC中的Global.asax文件
- ASP.NET的global.asax文件
- asp.net Global.asax文件的使用
- net 使用 Global.asax 文件
- ASP.NET全局文件Global.asax用法分析
- Global.asax 的用途原理
- asp.net mvc 错误 global.asax
- Global.asax 文件的作用
- Global.asax文件的使用
- Global.asax文件的使用
- Global.asax文件的作用
- Global.asax 文件的作用
- global.asax文件的作用
- Asp.Net中global.asax文件的描述
- Asp.Net中global.asax文件的描述
- opencv+gpu博客
- 2987: Earthquake
- python subprocess select 读取
- [ BSGS ] BZOJ2242
- python中 format格式字符串使用总结
- .Net MVC 里面的核心文件Global.asax运行原理分析
- QT3D学习之路02
- 优质内容-分享歌单《forward looking》
- 移动端ios:active伪类无效的兼容解决方案
- C++实现一个简易的内存池分配器
- 贪心专练5 删数问题
- Tomcat Connector三种运行模式(BIO, NIO, APR)的比较和优化
- opencv-2.4.9安装包及安装教程
- xxnet-deepin下使用