ABP vNext系列文章04---DynamicClient动态代理
一、动态代理在ABP系统中的应用
1、它主要在做什么事件
之前开发系统想要在后台调用别的服务都是用HttpClient发起请求,在abp vnext中不需要我们这样做了,
你只要知道服务调用的接口方法,就像调用本地代码一样调用接口,abp会动态生成一个http请求
这样,我们就引出了一个概念叫:动态 C# API 客户端
定义:ABP可以自动创建C# API 客户端代理来调用远程HTTP服务(REST APIS).通过这种方式,你不需要通过 HttpClient 或者其他低级的HTTP功能调用远程服务并获取数据.
2、如何申明一个远程的api接口
定义一个接口,只有一个条件:必须实现IRemoteService接口:
public interface IBookAppService : IApplicationService
{
Task<List<BookDto>> GetListAsync();
}
为了能自动被发现,你的接口需要实现IRemoteService接口.由于IApplicationService继承自IRemoteService接口.所以IBookAppService完全满足这个条件.
在你的服务中实现这个类,你可以使用auto API controller system将你的服务暴漏为一个REST API 端点.
3、添加 Volo.Abp.Http.Client nuget包
Install-Package Volo.Abp.Http.Client
增加的层为 HttpApi.Client
[DependsOn(typeof(AbpHttpClientModule))] //添加依赖
public class MyClientAppModule : AbpModule
{
}
4、创建客户端代理了.
例如:
[DependsOn(
typeof(AbpHttpClientModule), //用来创建客户端代理
typeof(MyApplicationContractsModule) //包含应用服务接口
)]
public class MyClientAppModule : AbpModule
{
private const string ProductRemoteServiceName = "ProductService";
public override void ConfigureServices(ServiceConfigurationContext context)
{
//创建动态客户端代理
context.Services.AddHttpClientProxies(
typeof(MyApplicationContractsModule).Assembly,ProductRemoteServiceName
);
}
}
AddHttpClientproxies方法获得一个程序集,找到这个程序集中所有的服务接口,创建并注册代理类.我们所有要调用的接口都是程序集 MyApplicationContractsModule 中的。
5、修改配置文件
appsettings.json文件中的RemoteServices节点被用来设置默认的服务地址.下面是最简单的配置:
{
"RemoteServices": {
"ProductService": {
"BaseUrl": "http://localhost:8012/",
"UseCurrentAccessToken": "true"
},
}
}
当设置 UseCurrentAccessToken 为true时说明请求是可以传送token的。那此时还要引用一个nuget包:Volo.Abp.Http.Client.IdentityModel,注意是要xxx.Host项目下引用,而不是xxx.HttpApi.Client层
并增加依赖:[DependsOn(typeof(AbpHttpClientIdentityModelModule))]
6、如何使用
可以直接在你的类中使用,就像调用本地接口一样,IBookAppService就是远程要调用的服务
public class MyService : ITransientDependency
{
private readonly IBookAppService _bookService; public MyService(IBookAppService bookService)
{
_bookService = bookService;
} public async Task DoIt()
{
var books = await _bookService.GetListAsync();
foreach (var book in books)
{
Console.WriteLine($"[BOOK {book.Id}] Name={book.Name}");
}
}
}
二、源码解析
在第一部分6节中,在使用注入接口IBookAppService时,在调用时其实是为我们生成一个代理接口去访问远程的api,也就是说当你调用接口时httpclient 拦截执并通过http形式执行你接口对应服务
我们找到和系统集成的地方,在项目HttpApi.Client 模块类中:

那我们就从这里开始源码的分析吧。此段代码是将模块中所有程序集和远程的地址传了进去,进入这个扩展方法AddHttpClientProxies,
扩展方法写在类ServiceCollectionHttpClientProxyExtensions中:

其中代码段:var serviceTypes = assembly.GetTypes().Where(IsSuitableForClientProxying).ToArray();就是从程序集中取出所有的符合要求的类,符合什么要求呢,我们再看看IsSuitableForClientProxying(ps:没想到方法在where中还可以这么调用,get了)

在这个方法中我们看到了一个非常亲切的接口IRemoteService,这就是我们自动api为什么要实现这个接口的原因了。
拿到我们所有符合要求的类后,通过foreach遍历,将符合要求的类,远程连接的地址继续往下传,调用方法AddHttpClientProxy,我们进这个方法看看做了些什么

可以看到,主要是将我们的接口,动态的去创建了一个实实,然后注入到容器中。
其中有一条经常用到的代码:typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptorType);
作用是为泛型类指定泛型类型,也就是原来是AbpAsyncDeterminationInterceptor<T>,泛型T不明确,现在明确了为 interceptorType
有一段非常重要也是核心的代码:

该方法主要是给我们的接口类Type(例如:IBookAppService ),动态的创建了一个实现类,并注入到ioc中,这样,我们在其它类中注入时,就有了该实例。
动态创建类是在第三方库中实现的,比较复杂,暂不研究,有兴趣可以参考开源:Https://github.com/castleproject/Core
ABP vNext系列文章04---DynamicClient动态代理的更多相关文章
- ABP vNext系列文章03---依赖注入
一.依赖注入的类型注册 ABP的依赖注入系统是基于Microsoft的依赖注入扩展库(Microsoft.Extensions.DependencyInjection nuget包)开发的.因此,它的 ...
- 2019 年起如何开始学习 ABP 框架系列文章-开篇有益
2019 年起如何开始学习 ABP 框架系列文章-开篇有益 [[TOC]] 本系列文章推荐阅读地址为:52ABP 开发文档 https://www.52abp.com/Wiki/52abp/lates ...
- 一步一步学习ABP项目系列文章目录
1.概述 基于DDD的.NET开发框架 - ABP初探 基于DDD的.NET开发框架 - ABP分层设计 基于DDD的.NET开发框架 - ABP模块设计 基于DDD的.NET开发框架 - ABP启动 ...
- [Abp vNext 源码分析] - 7. 权限与验证
一.简要说明 在上篇文章里面,我们在 ApplicationService 当中看到了权限检测代码,通过注入 IAuthorizationService 就可以实现权限检测.不过跳转到源码才发现,这个 ...
- Abp vNext 番外篇-疑难杂症丨浅谈扩展属性与多用户设计
说明 Abp vNext基础篇的文章还差一个单元测试模块就基本上完成了我争取10.1放假之前给大家赶稿出来,后面我们会开始进阶篇,开始拆一些东西,具体要做的事我会单独开一个文章来讲 缘起 本篇文章缘起 ...
- Android插件化原理解析——Hook机制之动态代理
转自 http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ 使用代理机制进行API Hook进而达到方法增强是框架的常 ...
- [Abp vNext 源码分析] - 11. 用户的自定义参数与配置
一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 23 日晚 更新日期:暂无 ABP vNext 针对用户可编辑的配置,提供了单独的 Volo. ...
- [Abp vNext 源码分析] - 12. 后台作业与后台工作者
一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 24 日晚 更新日期:暂无 ABP vNext 提供了后台工作者和后台作业的支持,基本实现与原 ...
- [Abp vNext 入坑分享] - 8.Redis与Refit的接入
前言 本章结束之后,这个abp vnext系列算是初步完结了,基础的组件都已经接入了.如果各位还需要其它的组件的话,可以自己按需要进行接入使用.其实这个只是一个基础的框架,可以自己根据需要进行变通的. ...
- jdk 动态代理的原理
一.代理设计模式 代理设计模式是Java常用的设计模式之一. 特点: 01.委托类和代理类有共同的接口或者父类: 02.代理类负责为委托类处理消息,并将消息转发给委托类: 03.委托类和代理类对象通常 ...
随机推荐
- 智能学习灯赛道竞争日趋激烈 火山引擎 VeDI 用数据技术助力打造新优势
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 智能学习灯的赛道正变得越来越拥挤. 2021 年 3 月 2 日,腾讯教育联合暗物智能科技联合发布"AILA 智 ...
- Linux系统用户态和内核态
Unix/Linux的体系架构 如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核空间).内核从本质上看是一种软件-----控制计算机的硬件资源,并提供上层应 ...
- windows使用rclone挂载alist为本地磁盘,设置开机自启
前言 实现在windows下将alist挂载为本地磁盘,并设置开机自启,使得重启后依然生效. 教程 下载软件 Rclone: Rclone downloads WinFsp: https://winf ...
- Beyond Compare常用快捷键
[会话]菜单的功能与快捷键 [文件]菜单的功能与快捷键 [编辑]菜单的功能与快捷键 [搜索]菜单的功能与快捷键
- 解决Github中使用Octotree时,出现 Error: API limit exceeded 报错 或者 Error: Connection error报错的问题(详细操作)
对于科研工作者来说,Github 是不可多得的利器,那么Octotree 插件的使用将会让用户在使用 Github 时拥有更好的体验,提高学习工作的效率.但是笔者在使用的过程中遇到以下这样的问题,下面 ...
- 2019年第十届蓝桥杯国赛C++B组
部分题目示意图来自网络,所以会带水印 最后编辑时间: 2021年5月12日 统一声明 如果不写默认带有常用头文件 如果不表明主函数默认表示在 void solve(){} 默认使用 using nam ...
- Ipa Guard使用手册
使用手册 开始使用ipa guard 代码混淆界面介绍 文件混淆-界面介绍 安装和登录Ipa Guard 相关教程 下载安装Ipa Guard ipaguard注册和登录 下载安装Ipa Guar ...
- 深度学习基础课:“判断性别”Demo需求分析和初步设计(下2)
大家好~我开设了"深度学习基础班"的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序 线上课程资料: 本节课录像回放1 本节课录像回 ...
- elementUI表格单选
html代码 <el-table :data="gkbmList" max-height="264" border @selection-change=& ...
- new关键字执行过程
在javascript中,现阶段我们可以采用三种方式创建对象(object) 利用字面量创建对象 利用new Object创建对象 利用构造函数创建对象 new关键字执行过程 // new关键字执行过 ...