MVC框架三大模块
1.Routing模块
Routing机制与MVC5的URL解析处理流程基本是相同的,很多的接口和类像IRouteHandler、IHttpHandler、IController 、RouteBase、RouteTable、RouteDictionary、DefaultControllerFactory以及AreaRegistration名称是相同的功能是类似的,也可以是看做MVC5路由机制的简化版本或者是Artech MVC5书中路由实例的强化版本。在Web项目的启动阶段,设置的路由模板(包括AreaRegistration中的)会被注册到RouteDictionary中,AppDomain中所有实现了IController接口的类型都会被注册到一个线程安全的集合中。
需要重点说明的时候,结合公司现有项目的实战经验(公司的开发规范),MVC项目的路由模板是很正规的,只能是这种形式Area/{otherParameter}/{controller}/{action}/{id},一个Segment只能是”/”或者纯文本字符串或者就单纯是一个大括号参数,不能即有参数又有文本字符串类似”/{date}text{time}/”或者”/{*parameter}/{ohterParameter}/”等等会造成路由复杂的特性(也不能使用RouteAttribute)。也无需RouteConstraint。所以我在解析请求的Url的工作量也降低了不少。
通过遍历缓存的Route集合,以Request作为参数,调用Route的Match方法,对比每个Route中的UrlTemplate和请求Url的虚拟路径,在文本字符串相同,参数位置相符的情况下将请求Url的对应结果或者Route中的默认参数值保存到RouteData的Values字典属性中。在解析出Area,Controller还有Action之后会调用DefaultControllerFactory,依据所匹配Route的DataTokens字典中存储的命名空间还有在项目中配置的默认命名空间来找到满足命名空间还有Controller名的Type。实例化并执行。
2.Action的参数绑定及执行
Action参数配置了五个来源分别是RouteData,QueryString,FormValue,FileCollection还有一个JsonValue,在执行参数绑定的时候,依优先级顺序获取用户指定的特定参数类型的绑定,如果未设置则调用DefaultModelBinder作为默认的绑定。DefaultModelBinder实施绑定还是相当复杂的难以讲述,同时在绑定的过程中还会执行ModelValidator,更新ModelState,总体而言,DefaultModelBinder会判断Action的参数是简单类型还是复杂类型,如果是复杂类型会使用反射解析出所有属性递归调用直到分解成所有简单类型执行绑定,所有复杂类型所分解出的属性会以字符串表达式()的形式传入那五个数据源来匹配是否有值,如果有就更新到ModelState。在表单中有时候需要上传文件,看到Nancy MVC框架中有套文件上传机制是通过解析Header中的boundary Token来获得文件Stream的就修改部分功能,并替换掉上下文然后加入到DrisionMVC中。
在完成参数的绑定后就开始执行Action的真正逻辑了,DrisionMVC为了提高效率,所有的Action都是以Action的MethodInfo为Key包装Action的ActionMethodDispatcher为Value,保存到一个线程安全的ActionMethodDispatcherCache字典中的,ActionMethodDispatcher的Execute方法会完成真正的逻辑执行,Action会被包装到一个LamdaExpression中,形式为Func<object, object[], Task<object>>,该LamdaExpression同样会被缓存,被获取执行就能返回正确的结果。
3.视图cshtml文件的编译执行
View视图文件的编译参照的是RazorEngine框架,所有的.cshtml文件在被第一次编译成C#类后都会被保存到一个线程安全的字典中。该框架的大体运行流程是在控制器的Action方法中返回View()时会调用ViewResult类的ExecuteResult方法,该方法体中开始调用RazorEngine的编译和执行功能,根据约定获取到视图.cshtml文件的绝对路径,以该绝对路径和视图Model的类型(不存在就为null)为组合key,查找缓存中是否存在已经编译好的视图实例,存在就直接返会视图实例,执行视图实例返回一个完整的html字符串文本并写入到Response的Body属性中。如果不存在就会首先获取到.cshtml文件的全部文本,同时新建一个TypeContext的实例包含,Model的Type类型,还有被编译生成的C#类的基类RazorTemplateBase<>还有所必需的的命名空间集合。传入Roslyn编译器生成真正的C#类型并保存。不过现在还有一个问题就是在视图cshtml中应用了@model ModeType之后调用@Html.TextBoxFor等等空间的时候没有智能提示也是挺头疼的,目前暂时使用@inherits来替代。
开发的过程中发现RazorEngine并没有@Html(HtmlHelper)和@Url(UrlHelper)的帮助类,所以在使用DrisionMVC开发Web项目就无法使用控件了,像@Html.TextBox,@Html.DropdowList,@Html.Action还有@Url.Action之类的。所以在RazorTemplateBase<>基类中自定义了HtmlHelper,还有UrlHelper两个属性,所有控件的Render机制都与MVC5只是修改成使用OwinContext作为数据源。另外子Action机制还有Partial也是比较复杂的,花了不少的精力。View视图的两大重量级的控件DisplayFor,EditorFor因为公司里面项目都为使用所以未添加。
经过几个月的奋战终于完成了这套MVC框架,在测试应用的过程中问题很少并且没有出现架构级的错误造成某些MVC5常用功能无法实现,也是倍感欣慰。感觉学到了很多的东西,高内聚松耦合的思想也是颇有体会,也学习了不少框架开发的注意事项。
MVC框架三大模块的更多相关文章
- MVC框架浅析(基于PHP)
MVC框架浅析(基于PHP) MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数 ...
- .Net MVC 框架基础知识
一.什么是MVC? MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式. MVC全名是Model View Controlle ...
- 编写自己的PHP MVC框架笔记
1.MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller). ...
- 分享一实战性开源MVC框架<Linux、Windows跨平台开发so easy>
一.引子 开源地址 https://github.com/564064202/Moon.Mvc 欢迎加入开发 .NET Core微软还在发力,但作为商用还有一段距离,很多开发库尚不能用于.NET ...
- 产品前端重构(TypeScript、MVC框架设计)
最近两周完成了对公司某一产品的前端重构,本文记录重构的主要思路及相关的设计内容. 公司期望把某一管理类信息系统从项目代码中抽取.重构为一个可复用的产品.该系统的前端是基于 ExtJs 5 进行构造的, ...
- MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...
- MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)
前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...
- Spring MVC 框架的架包分析,功能作用,优点
由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或是软件架构师,在学习和了解一个框架的时候,首先都应该知道的是这个框架的原理和与其有关j ...
- 自己动手写一个简单的MVC框架(第二版)
一.ASP.NET MVC核心机制回顾 在ASP.NET MVC中,最核心的当属“路由系统”,而路由系统的核心则源于一个强大的System.Web.Routing.dll组件. 在这个System.W ...
随机推荐
- Java广度优先爬虫示例(抓取复旦新闻信息)
一.使用的技术 这个爬虫是近半个月前学习爬虫技术的一个小例子,比较简单,怕时间久了会忘,这里简单总结一下.主要用到的外部Jar包有HttpClient4.3.4,HtmlParser2.1,使用的开发 ...
- No edit session in the progress
运行环境:开发环境:Windows7旗舰版64bit.VisualStudio2008 With SP1.ArcEngine10.0.NetFrameWork4.0.IIS7和C#开发语言. 问题描述 ...
- C# SHA1散列算法
C# SHA1散列算法 /// <summary> /// C# SHA1散列算法 /// </summary> /// <param name="str&qu ...
- XUtils——GET请求
//HttpUtils实例化对象 HttpUtils http = new HttpUtils(); /* *发送请求send(HttpMethod ...
- 如何查看SharePoint未知错误的详细信息
在sharepoint 开发的时候,需要查看具体的sharepoint报错信息需要在配置文件中配置如下 通过下面方法就可以直接在出错页面查看错误信息.修改Web应用程序根目录上的Web.config文 ...
- 移动APP开发使用什么样的原型设计工具比较合适?
原型设计工具有Axure,Balsamiq Mockups,JustinMind,iClap原型工具,等其他原型工具.其中JustinMind比较适合APP开发使用. JustinMind可以输出Ht ...
- Jackson fasterxml跟codehaus的区别 (fasterxml vs. codehaus) -- 转载
Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用新的包名fasterxml:1.x版本的包名是cod ...
- 《笨办法学C》笔记之指针
C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...
- Hibernate中的HQL查询与缓存机制
HQL:完全面向对象查询 SQL的执行顺序: 1.From 2.Where 过滤基础数据 where与having的区别:1.顺序不同 2.where过滤基础数据 3. 过滤聚合函数 3.Group ...
- 关于String中+与StringBuilder的问题
字符串连接可以通过两种方法实现,其中一种是在Java中提供的一个StringBuilder类(这个类只在J2SE5及以上版本提供,以前的版本使用StringBuffer类). 字符串是Java程序 ...