文章目录

前情概要

前边的文章把一些基本的前置任务都完成了。接下就是比较重要的处理函数action是如何自动发现和注册的拉,也就是入口函数RouteHandler(也是我们的第一个express中间件)里面的一些细节。

扫描action并添加到缓存

说一说我们的思路,其实和静态语言中的反射概念有点类似。

  1. 循环传进来的所有controller声明。详见 控制器的声明和定义篇---controller注册到RouteHandler
  2. 循环所有声明的controllers,并将每一个controller里面的action添加到action缓存中。

关键方法也就是Object.getOwnPropertyNames和Object.getOwnPropertyDescriptor2个方法了。目的则是对象上的所有成员,对应到比如说.net,java之类的就是反射拉。

export function RouteHandler(app: core.Express, controllers: any) {
find(controllers)
//app.use('/', (req, res, next) => 。。。。。。
}
function find(controllers: any) {
//controllers本质上是一个对象,类似:{host:{},home:{},site:{}}。那我们这里的key就是controller的名字,value就是controller实列了。
var _reg_controller_names = Object.getOwnPropertyNames(controllers)//对象上所有成员,就是我们所有的controller名称集合。
for (var index = 0; index < _reg_controller_names.length; index++) {
var _reg_controller_name = _reg_controller_names[index];//controller的名称,比如:home
var _reg_controller_Desc = Object.getOwnPropertyDescriptor(controllers, _reg_controller_name) as PropertyDescriptor//controller的描述对象
if (_reg_controller_name === '__esModule') continue; var cType = _reg_controller_Desc.value;//controller的类型,比如:Homecontroller
var cName = cType.name;//controller的class名称。比如"HomeController"; var aNames = Object.getOwnPropertyNames(cType.prototype)//controller所有成员,也就是我们的action
for (var index2 = 0; index2 < aNames.length; index2++) {
var aName = aNames[index2];
if (aName === 'constructor') continue;
var aType = (Object.getOwnPropertyDescriptor(cType.prototype, aName) as PropertyDescriptor).value//具体的每一个action函数
SetActionDescriptor(cName, aName, undefined, undefined, _reg_controller_name, cType, aType)//加入缓存
//第三个参数[httpMethod] 请求方法类型。默认给undefined,后续再通过扫描action上面的特性标签增加进来
//第四个参数 [actionName] 路由action名字。默认给undefined,后续再通过扫描action上面的特性标签增加进来
}
}
}

SetActionDescriptor的实现

/**
*
*
* @export
* @param {string} controllerTypeName 控制器类型名字
* @param {string} actionTypeName 方法类型名字
* @param {string} [httpMethod] 请求方法类型
* @param {string} [actionName] 路由action名字
* @param {string} [controllerName] 路由控制器名字
* @param {*} [controllerType] 控制器对象
* @param {*} [actionType] action 对象
* @returns {ActionDescriptor}
*/
export function SetActionDescriptor(controllerTypeName: string, actionTypeName: string, httpMethod?: string, actionName?: string, controllerName?: string, controllerType?: any, actionType?: any, isAuth?: boolean): ActionDescriptor { var _actions = _dic_override.get(controllerTypeName)
if (!_actions) {
_actions = new Map<string, ActionDescriptor>();
_dic_override.set(controllerTypeName, _actions)
}
var _action = _actions.get(actionTypeName);
if (!_action) {
_action = new ActionDescriptor();
_actions.set(actionTypeName, _action)
}
_action.ControllerTypeName = controllerTypeName;
_action.ActionTypeName = actionTypeName; if (!_action.ActionName)
_action.ActionName = actionTypeName if (httpMethod)
_action.HttpMethod = httpMethod.toUpperCase(); if (controllerType)
_action.ControllerType = controllerType;
if (controllerName)
_action.ControllerName = controllerName; if (actionName)
_action.ActionName = actionName;
if (actionType)
_action.ActionType = actionType if (isAuth === true || isAuth === false)
_action.isAuth = isAuth; _action.Id = _action.ActionName + (_action.HttpMethod ? ('_' + _action.HttpMethod) : '') return _action
}

SetActionDescriptor方法参数有值得情况下则更新,没有值则跳过。因为针对同一个action可能会被调用多次。对一个action的描述信息也是分部分分多次set进来的。一部分是通过对象的原型,还有一部分则是ts的装饰器(后端语言的attribute)。

需要注意的是每个action有个id字段。id字段使用http method和action name 来拼接。

【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--控制器和处理函数的注册篇(4/8)【controller+action】的更多相关文章

  1. 七天学会ASP.NET MVC (三)——ASP.Net MVC 数据处理

    第三天我们将学习Asp.Net中数据处理功能,了解数据访问层,EF,以及EF中常用的代码实现方式,创建数据访问层和数据入口,处理Post数据,以及数据验证等功能. 系列文章 七天学会ASP.NET M ...

  2. 七天学会ASP.NET MVC (三)——ASP.Net MVC 数据处理 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_three.html 第三天我们将学习Asp.Net中数据处理功能,了解数据访问层,EF,以及EF中常用的代码实 ...

  3. 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递

    通过第一天的学习之后,我们相信您已经对MVC有一些基本了解. 本节所讲的内容是在上节的基础之上,因此需要确保您是否掌握了上一节的内容.本章的目标是在今天学习结束时利用最佳实践解决方案创建一个小型的MV ...

  4. 【MVC】ASP.NET MVC Forms验证机制

    http://www.cnblogs.com/bomo/p/3309766.html 随笔 - 121  文章 - 0  评论 - 92 [MVC]ASP.NET MVC Forms验证机制 ASP. ...

  5. 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性

    [索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...

  6. asp.net mvc ,asp.net mvc api 中使用全局过滤器进行异常捕获记录

    MVC下的全局异常过滤器注册方式如下:标红为asp.net mvc ,asp.net mvc api  注册全局异常过滤器的不同之处 using SuperManCore; using System. ...

  7. 返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller

    原文:返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller [索引页][源码下载] 返璞归真 asp.net mvc (7) - asp.net ...

  8. 返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model

    原文:返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model [索引页][源码下载] 返璞归真 asp.net mvc (8) - asp.net mvc ...

  9. 返璞归真 asp.net mvc (12) - asp.net mvc 4.0 新特性之移动特性

    原文:返璞归真 asp.net mvc (12) - asp.net mvc 4.0 新特性之移动特性 [索引页][源码下载] 返璞归真 asp.net mvc (12) - asp.net mvc ...

随机推荐

  1. 6.1Python文件的操作(一)

    目录 目录 前言 (一)基础类型 ==1.只读== ==2.只写== ==3.追加== (二)b二进制组合 ==1.读写二进制文件== (三)+ 附加组合 ==1.读附加== ==2.写附加== == ...

  2. Nginx禁止目录执行php文件权限

    location ~ /dir/.*.(php|php5)?$ { deny all; } 禁止dir目录执行php文件权限 .csharpcode, .csharpcode pre { font-s ...

  3. el-table-column v-if条件渲染报错h.$scopedSlots.default is not a function

    我们在实际项目中经常会遇到el-table-column条件渲染出现报错的情况 报错内容: h.$scopedSlots.default is not a function 究其原因,是因为表格是el ...

  4. 【转】一个域名是用哪里的DNS来解析的,电脑怎么知道找哪一个DNS呢? 我注册域名的时候会在服务商那里配置DNS解析,一般需要24小时后才能访问,我想知道,解析后的这个数据是不是会同步到世界上所有的DNS服务器呢!如果不是,当我访问我的这个域名的时候,电脑怎么知道去找到我注册的这一家的DNS服务器呢,谁告诉他的呢?

    看看DNS一些基础知识,你就了解了.1.DNS就是域名服务器,他的任务就是确定域名的解析,比如A记录MX记录等等. 2.任何域名都至少有一个DNS,一般是2个.为什么要2个以上呢?因为DNS可以轮回处 ...

  5. vue 实现tab切换动态加载不同的组件

    vue 实现tab切换动态加载不同的组件 使用vue中的is特性来加载不同的组件.具体看如下代码:这个功能对于vue比较复杂的页面可以使用上,可以把一个页面的功能拆分出来,使代码更简单.使用方式具体看 ...

  6. python基础学习第五天

    li=[1,2,33,-1,'dbssd',[4,5,6],{4:'rfw',5:'re'}]del(li[1])print(li)print(type(li))#访问元素print(li[0])pr ...

  7. 【Codeforces 3D】Least Cost Bracket Sequence

    Codeforces 3 D 题意:有一个括号序列,其中一些位置是问号,把第\(i\)个问号改成(需要\(a_i\)的代价,把它改成)需要\(b_i\)的代价. 问使得这个括号序列成立所需要的最小代价 ...

  8. C++ 文件和流

    到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流. 本教程介绍如何从文件读取流和向文件写入流.这就需要用到 C++ ...

  9. jmeter(四)HTTP请求

    启动jmeter,建立一个测试计划 这里再次说说怎么安装和启动jmeter吧,昨天下午又被人问到怎样安装和使用,我也是醉了:在我看来,百度能解决百分之八十的问题,特别是基础的问题... 安装:去官网下 ...

  10. WebSphere下配置HTTP压缩

    WebSphere下配置HTTP压缩 背景 WebSphere本身的安装配置中并不包含HTTP压缩的模块,而是通过新增WebServer来实现的,WebSphere通过Plugin与WebServer ...