看蒋老师MVC的书第二个大收获可以是算是看了这个迷你ASP.NET MVC框架了,虽然它远不如真正ASP.NET MVC(下文简称“MVC”)那么复杂庞大,但在迷你版中绕来绕去也够呛的。这部分我看了几回,也没完完全全地弄清里面的结构,但要透彻了解整个MVC框架,贯通了整个迷你MVC框架必不可少,没了迷你的作为基础,在看完整框架时也不知道走到哪一步了。贯通整个框架虽然复杂,但我觉得可以从分层次的角度去看整个框架,化整为零,那么难度就降下来了。
首先对于平常的Http请求来了,服务器对作相应的处理,处理完毕之后就会给浏览器一个Http响应。最简单的就是浏览器发出来一个对index.htm页面的请求,服务器就会读取index.htm文件的内容然后把内容包含在报文里面传递给浏览器昨晚响应。这个就是单纯的URL与物理文件绑定,在ASP.NET里面多加了路由机制,它就使得URL与物理文件分离。MVC里面其中一个重要部分就是路由机制,整个请求响应过程就变成了
也就是接收到一个请求之后用IhttpModule接口把请求拦截下来,按照路由规则分析了URL并匹配好对应的路由之后,用一个实现IHttpHandler接口的类的实例去做相应的处理,处理完毕就返回HttpResponse到浏览器。这个就是MVC框架的最顶层部分了。在这里我们还没看到平时在使用MVC是接触到的Route,Controller和Action。如果跟两个接口扯上关系的话,那就是Route主要是在HttpModule部分被使用,Controller和Action是在HttpHandler部分被使用。大框架已经定好的话,现在可以细化了,可以分别从HttpModule和HttpHandler去看整个流程。
IHttpModule
由UrlRouteModule去实现这个接口,处理过程大致是根据当前的请求上下文,构造HttpContextWapper对象。通过全局路由表来匹配当前请求的URL,获取到路由之后就通过路由和HttpContextWapper构造出请求上下文(RequestContext),从路由中获取一个实现IRouteHandler接口的类的实例,那是个MvcRouteHandler的实例,从那个实例中调用GetHttpHandler方法获取到一个实现IHttpHandler接口的类的实例,最后从通过HttpContextWapper把IHttpHandler更替过去,IHttpModule的部分就完结了,接下来到HttpHandler部分的处理了。整个处理的流程也如下图所示
IHttpHandler
由MvcHandler来实现这个接口,在HttpModule部分已经把路由对象处理好了,MVC中剩下的调用控制器中的行为方法,传入参数,绑定相关模型,处理完毕之后返回一个ActionResult,最终通过视图的内容作为响应报文呈现在浏览器上。MvcHandler的处理就在ProcessRequset方法里执行。详细的流程如下,首先从传入的HttpRequestContext中获取控制器的名字,Controller控制器是通过控制器工厂获取的,控制器工厂是从ControllerBuilder中得到。Controller执行Execute方法,传入RequestContext参数。就会执行相应的行为方法。流程如下图
但是其实还有更多操作包含在Execute方法里面,因为还需要执行行为方法,从Route中获取参数传到行为方法里面,返回ActionResult等。
在ControllBase调用Execute方法里,通过传入的请求上下文(RequestContext)和控制器自身构造出一个控制器上下文(ControllerContext),最后调用一个实现IActionInvoker的接口执行行为方法,如下图所示
这里又有一个InvokeAction方法,里面核心部分就是通过反射调用Controller的行为方法,至于行为方法需要传入的参数,生成ParameterInfo实例是通过了调用IModelBinder接口的方法,通过上下文获取路由的参数,也是利用了反射机制设值。方法调用完毕后返回的是一个ActionResult抽象类的实例,那么最后执行了ActionResult的ExecuteResult方法,把响应的页面的内容生成出来。如下图所示
HttpHandler的操作就分成了这几块,如果凑在一起的话,图成这样了
对于HttpModule部分,有几个类的关系还是要理顺一下。
整幅图其实没有按照UML的格式去画的,那个我也已经忘了,我画图的目的在于罗列各个类,而且把类与类之间的调用标示出来,对于一个方法,从类图左侧引线出去的,那是返回,从右侧引线出去的那是传入。
整个框架用的接口还是挺多的,这个觉得就能给我一种达到解耦的目的。方法的调用不通过类来直接调用,而是通过接口的调用,这样就排除了主调类对被调类的访问,不需要知道其细节。
以上便是我对迷你MVC的学习笔记,可能有些园友觉得我多此一举,不管怎样多了解一点还是有好处的,以上有理解错的欢迎大家指出,谢谢!
熟悉其情况 查看其结构 理解其本质 思考其改进