ABP框架详解(八)动态ApiController的生成和访问机制

  在ABP框架中提供了一套动态生成ApiController的机制(依然支持原生ApiController的使用方式),虽然说是动态生成ApiController但是实际上并没有真正在启动程序的时候生成任何ApiController类的子类,客户端所有对动态控制器的访问都集中到同一个泛型类DynamicApiController<T>上。真正用来区别不同服务的是其泛型T,这是一个继承自IApplicationService的接口,用户自定义的应用服务类继承T接口并实现其中的方法。系统在启动阶段会自动注册所有应用服务类。

  实际上动态控制器之所以能工作就是依赖IApplicationService在程序开始阶段已经被注册到容器中。ABP框架中存在一个拦截器AbpDynamicApiControllerInterceptor<T>,在DynamicApiController<T>控制器类型上添加接口代理(IApplicationService的子类)也就是说对该控制器类型的任何应用服务方法的访问都会被拦截,利用拦截器的构造函数public AbpDynamicApiControllerInterceptor(T proxiedObject),将应用服务的真实类型解析进去,然后通过反射执行应用服务中的方法。比较漂亮的一点就是自定义的AbpApiControllerActionSelector和DynamicHttpActionDescriptor类,在Selector的SelectAction方法中会新建一个DynamicHttpActionDescriptor实例,并将IApplicationService子接口的方法MethodInfo传递进去,这样就可以利用WebApi原生的参数绑定机制完成参数的获取了。

  在程序的开始阶段调用DynamicApiControllerBuilder的泛型方法ForAll<T>(Assembly assembly, string servicePrefix)找到assembly中所有T的自定义子接口,根据子接口及其中定义的方法包装成DynamicApiControllerInfo和DynamicApiMethodInfo存储到DynamicApiControllerManager静态类中字典字段中,以后需要获取任意一个控制器的信息也是通过该静态类根据Servic的名字来获得的。

  访问的话就没有多少好说的了,在DynamicApiControllerBuilder收集所有应用服务信息来生成DynamicApiControllerInfo的时候可以指定Prefix,以后所有希望调用IApplicationService的Request都需要有该前缀,至于服务的名称默认是IApplicationService的子接口名(像“ApplicationService”,”AppService“等等几个后缀还是需要去掉的,最前面“I”也是要删掉的),当然后可以定义一个委托Func<Type, string> _serviceNameSelector,来自定义服务名,再就是在服务名的后面添加方法名来唯一定位到应用服务的Action。别忘了定义Route,系统默认定义了一个services为前缀的动态控制器的RouteTemplate。

转载于:https://www.cnblogs.com/Azula/p/5320547.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三、Java Web中出现的一些乱码问题总结(详解)

一、response.getWriter().write(&#xff09;和 response.getWriter().print(&#xff09;的区别 response.getWriter()返回的是PrintWriter&#xff0c;这是一个打印输出流 response.getWriter().write(&#xff09;和 response.getWriter().print(&#xff09;是响应给客户…

LeetCode 2325. 解密消息(map)

文章目录1. 题目2. 解题1. 题目 给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。 解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。将替换表与普通英文字母表对齐&#xff0c;形…

结对项目——最大子数组

求数组中最大子数组的和 一、程序要求 1、返回一个整数数组中最大子数组的和&#xff1b; 2、输入一个整数数组&#xff0c;数组中有正数也有负数&#xff1b; 3、数组中连续的一个或多个整数组成一个子数组&#xff0c;每个子数组都有一个和&#xff1b; 4、求所有子数组的和的…

python的GUI编程和tkinter学习笔记——第一个GUI程序

一、第一个GUI程序 from tkinter import * from tkinter import messagebox# 创建窗口 root Tk()btn01 Button(root) btn01["text"] "点我就送花"btn01.pack()def songhua(e): # e就是事件对象messagebox.showinfo("Message","送你一朵…

LeetCode 2331. 计算布尔二叉树的值(树的遍历)

文章目录1. 题目2. 解题1. 题目 给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a; 叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。非叶子节点 要么值为 2 要么值为 3 &#xff0c;其中 2 表示逻辑或 OR &#…

linux内核启动以及文件系统的加载过程

Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令&#xff0c;就进入 Linux 内核启动阶段。普通 Linux 内核的启动过程也可以分为两个阶段。本文以项目中使用的 linux-2.6.37 版源码为例分三个阶段来描述内核启动全过程。第一阶段为内核自解压过程&#xff0c…

LeetCode 2335. 装满杯子需要的最短总时长

文章目录1. 题目2. 解题1. 题目 现有一台饮水机&#xff0c;可以制备冷水、温水和热水。每秒钟&#xff0c;可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。 给你一个下标从 0 开始、长度为 3 的整数数组 amount &#xff0c;其中 amount[0]、amount[1] 和 amount[2] 分…

HDU-4089 Activation (概率DP求概率)

题目大意&#xff1a;一款新游戏注册账号时&#xff0c;有n个用户在排队。每处理一个用户的信息时&#xff0c;可能会出现下面四种情况&#xff1a; 1.处理失败&#xff0c;重新处理&#xff0c;处理信息仍然在队头&#xff0c;发生的概率为p1&#xff1b; 2.处理错误&#xff…

Linux实操篇——实用指令学习笔记(详解)

9.3帮助指令 9.3.1介绍 当我们对某个指令不熟悉时&#xff0c;我们可以使用Linux提供的帮助指令来了解这个指令的使用方法。 9.3.2man 获得帮助信息 基本语法 man[命令或配置文件]&#xff08;功能描述&#xff1a;获得帮助信息&#xff09;应用实例 案例&#xff1a;查看1…

LeetCode 2249. 统计圆内格点数目

文章目录1. 题目2. 解题1. 题目 给你一个二维整数数组 circles &#xff0c;其中 circles[i] [xi, yi, ri] 表示网格上圆心为 (xi, yi) 且半径为 ri 的第 i 个圆&#xff0c;返回出现在 至少一个 圆内的 格点数目 。 注意&#xff1a; 格点 是指整数坐标对应的点。 圆周上的…

Python实现自动发送邮件(详解)

Python实现自动发送邮件 1.开启SMTP服务 为了实现自动发送邮件的目的&#xff0c;我们需要在邮箱中开启SMTP服务&#xff1a; 这点很关键&#xff0c;别忘了去开启SMTP&#xff0c; 别忘了去开启SMTP&#xff0c;否则邮件是无法发送成功的 。然后你还需要点击下面生成授权…

unity 常用函数

GameObject.FindGameObjectByTag(); anim.SetFloat("speed",Mathf.Abs(h)); Physics2D.lineCast2D(transform.position,groundCheck.position,1<<LayerMask.NameToLay("ground")); AddForce(); 转载于:https://www.cnblogs.com/yufenghou/p/5325092.…

React 组件:计时器例子

文章目录1. 将应用程序分解为组件2. 构建应用静态版本3. 哪些组件是有状态的4. 每个 state 应该在哪个组件里5. 硬编码初始化state6. 添加反向数据流7. 添加服务器通信learn from 《React全家桶&#xff1a;前端开发与实例详解》https://zh-hans.reactjs.org/tutorial/tutorial…

一、快速开始一个 MyBatis项目(详解)

1.0 概述 1.三层架构 界面层&#xff1a; 和用户打交道的&#xff0c; 接收用户的请求参数&#xff0c; 显示处理结果的。&#xff08;jsp &#xff0c;html &#xff0c;servlet&#xff09; 业务逻辑层&#xff1a; 接收了界面层传递的数据&#xff0c;计算逻辑&#xff0c;…

2013 ACM区域赛长沙 K Pocket Cube hdu 4801

题意:给了一个2*2的魔方..每步操作可以将任意一面翻转90度..现在问在N(<7)步内.最多能翻出几面相同的. 直接打表模拟每种翻转情况 1 #include<cstdio>2 #include<cstring>3 #include<algorithm>4 #include<iostream>5 using namespace std;6 7 int …

React 组件和服务器

文章目录1. 请求服务器数据2. 发送开始停止请求3. 发送创建、删除、更新请求learn from 《React全家桶&#xff1a;前端开发与实例详解》https://zh-hans.reactjs.org/tutorial/tutorial.htmlhttps://zh-hans.reactjs.org/docs/create-a-new-react-app.html#create-react-app服…

二、MyBatis常用对象分析 封装工具类

1.0 MyBatis 对象分析 &#xff08;1&#xff09; Resources 类 Resources 类&#xff0c;顾名思义就是资源&#xff0c;用于读取资源文件。其有很多方法通过加载并解析资源文件&#xff0c;返回不同类型的 IO 流对象。 &#xff08;2&#xff09; SqlSessionFactoryBuilder…

Java的几个同步辅助类

Java为我们提供了一些同步辅助类&#xff0c;利用这些辅助类我们可以在多线程编程中&#xff0c;灵活地把握线程的状态。 CountDownLatch CountDownLatch一个同步辅助类&#xff0c;在完成一组正在其他线程中执行的操作之前&#xff0c;它允许一个或多个线程一直等待。 再Count…

iOS图片拉伸技巧

纵观移动市场&#xff0c;一款移动app&#xff0c;要想长期在移动市场立足&#xff0c;最起码要包含以下几个要素&#xff1a;实用的功能、极强的用户体验、华丽简洁的外观。华丽外观的背后&#xff0c;少不了美工的辛苦设计&#xff0c;但如果开发人员不懂得怎么合理展示这些设…

LeetCode 2341. 数组能形成多少数对

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返…