一、动态代理在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动态代理的更多相关文章

  1. ABP vNext系列文章03---依赖注入

    一.依赖注入的类型注册 ABP的依赖注入系统是基于Microsoft的依赖注入扩展库(Microsoft.Extensions.DependencyInjection nuget包)开发的.因此,它的 ...

  2. 2019 年起如何开始学习 ABP 框架系列文章-开篇有益

    2019 年起如何开始学习 ABP 框架系列文章-开篇有益 [[TOC]] 本系列文章推荐阅读地址为:52ABP 开发文档 https://www.52abp.com/Wiki/52abp/lates ...

  3. 一步一步学习ABP项目系列文章目录

    1.概述 基于DDD的.NET开发框架 - ABP初探 基于DDD的.NET开发框架 - ABP分层设计 基于DDD的.NET开发框架 - ABP模块设计 基于DDD的.NET开发框架 - ABP启动 ...

  4. [Abp vNext 源码分析] - 7. 权限与验证

    一.简要说明 在上篇文章里面,我们在 ApplicationService 当中看到了权限检测代码,通过注入 IAuthorizationService 就可以实现权限检测.不过跳转到源码才发现,这个 ...

  5. Abp vNext 番外篇-疑难杂症丨浅谈扩展属性与多用户设计

    说明 Abp vNext基础篇的文章还差一个单元测试模块就基本上完成了我争取10.1放假之前给大家赶稿出来,后面我们会开始进阶篇,开始拆一些东西,具体要做的事我会单独开一个文章来讲 缘起 本篇文章缘起 ...

  6. Android插件化原理解析——Hook机制之动态代理

    转自 http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ 使用代理机制进行API Hook进而达到方法增强是框架的常 ...

  7. [Abp vNext 源码分析] - 11. 用户的自定义参数与配置

    一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 23 日晚 更新日期:暂无 ABP vNext 针对用户可编辑的配置,提供了单独的 Volo. ...

  8. [Abp vNext 源码分析] - 12. 后台作业与后台工作者

    一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 24 日晚 更新日期:暂无 ABP vNext 提供了后台工作者和后台作业的支持,基本实现与原 ...

  9. [Abp vNext 入坑分享] - 8.Redis与Refit的接入

    前言 本章结束之后,这个abp vnext系列算是初步完结了,基础的组件都已经接入了.如果各位还需要其它的组件的话,可以自己按需要进行接入使用.其实这个只是一个基础的框架,可以自己根据需要进行变通的. ...

  10. jdk 动态代理的原理

    一.代理设计模式 代理设计模式是Java常用的设计模式之一. 特点: 01.委托类和代理类有共同的接口或者父类: 02.代理类负责为委托类处理消息,并将消息转发给委托类: 03.委托类和代理类对象通常 ...

随机推荐

  1. PPT 常见的页面框架

    分割 分列 居中 包围 对称 杂志 https://www.bilibili.com/video/BV1ha411g7f5?p=19

  2. Ajax请求 content_type ajax发送Fromdata对象

    目录 Ajax请求入门 ajax实现简单计算器 content_type urlencode fromdata application/json 自定义request.JSON ajax发送Fromd ...

  3. shell 里使用 sed awk

    1 在shell脚本里使用sed 需把''改为"" 2 在shell脚本里使用awk 正则里使用 变量加上单引 awk -F: '/^'$user_name'/{print $1, ...

  4. [VS Code] 入门-自定键盘快捷键

    Keyboard Shortcuts 自訂鍵盤快捷鍵 開啟設定面板 :點擊左下角管理圖示〉選擇「鍵盤快速鍵」. 編輯器開啟後,滑鼠移至變更項目上,點擊出現的變更圖示(橘框處),輸入要變更的快捷鍵組合. ...

  5. AtCoder Beginner Contest 177 (个人题解,C后缀和,D并查集,E质因数分解)

    补题链接:Here A - Don't be late 题意:高桥(Takahashi )现在要去距离家 \(D\) 米的地方面基,请问如果以最高速度 \(S\) 能否再 \(T\) 时刻准时到达? ...

  6. vivo 云服务海量数据存储架构演进与实践

    一.写在开头 vivo 云服务提供给用户备份手机上的联系人.短信.便签.书签等数据的能力,底层存储采用 MySQL 数据库进行数据存储. 随着 vivo 云服务业务发展,云服务用户量增长迅速,存储在云 ...

  7. 3D编程模式:介绍设计原则

    大家好~本文介绍6个设计原则的定义 系列文章详见: 3D编程模式:开篇 目录 单一职责原则(SRP) 依赖倒置原则(DIP) 接口隔离原则(ISP) 迪米特法则(LoD) 合成复用原则(CARP) 开 ...

  8. vue项目部署的最佳实践

    前言 使用vue.react.angular等技术开发过程中,我们都会遇到以下问题: 首屏加载慢 每一次更新都需要清除浏览器缓存才能看到效果(经常被测试吐槽) 这两个问题可以从很多方面进行优化,今天我 ...

  9. Java面试——数据库知识点

    MySQL 1.建 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合.一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null). 超键:在关系中能唯一标识元组的属性 ...

  10. 关闭 cockpit 登陆提示

    sudo rm /etc/issue.d/cockpit.issue sudo rm /etc/motd.d/cockpit