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 ...
随机推荐
- 安卓app中嵌入一个H5页面,当手机系统设置字体变大时,如何使H5页面的字体不会随用户自己调整的系统字体变化而变化?
webview.getSettings().setTextZoom(100);WebView加上这个设置后,WebView里的字体就不会随系统字体大小设置发生变化了. https://segmentf ...
- ABP mapto 映射
obj1.MapTo(obj2); obj1=>obj2: 在obj1实体里添加映射 [AutoMap(typeof(obj2))] public class obj1 { }
- Ajax 知识点
AJAX 即"Asynchronous Javascript And XML"(异步JavaScript和XML) Ajax 不是某种编程语言,只是一种在无需重新加载整个网页的情况 ...
- Android进程间的通信之Messenger
Android进程间的通信方式可以通过以下两种方式完成: Android接口定义语言(AIDL) 使用Messenger绑定服务 本文我们将学习使用Messenger绑定服务的方式进行进程间的通信. ...
- [工具.tfs]可视化的TFS命令工具——Team Foundation Sidekicks
工具介绍:http://www.attrice.info/cm/tfs/index.htm Team Foundation Sidekicks is a suite of tools for Micr ...
- Valid Parentheses 使用递归的解法
class Solution { public: bool isValid(string s) { ||s.size()%!=)return false; unordered_map<char, ...
- PTGM and APTM
1. 性能测试过程模型(PTGM) PTGM模型包括以下几个步骤: 测试前期的准备 测试工具的引入 测试计划 测试设计与开发 测试执行与管理 测试分析 测试前期准备:主要任务为保证系统稳定和建立合适的 ...
- Android框架之AndroidAnnotations实战
方案一: 下载 androidannotations-bundle-3.3.2.zip 方案二: 楼主选用开发环境:android studio 新建项目 修改app 下的build.gradl ...
- win10 virtualbox5, ubuntu16.04 xshell5配合使用
这个搭配很好用,各软件的安装很容易,ubuntu安装进virtualbox后安装增强功能,然后将网络连接方式改为桥接,直接改为桥接就可以了,其他的不用变,这个比以前的版本好用多了.这个桥接解决了宿主机 ...
- XMLHttpRequest cannot load file:///E:/userdialog.html?_=1465888805734. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-reso
做前端写静态页面时,采用的是jq easyui框架 在ie与webkit总是加载的时候总是在loading... 而firefox却是正常加载的,总以为是代码写错了, 经过再三的检查以及百度查找,确认 ...