一、动态代理在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. ios安全加固 ios 加固方案

    ​ 目录 一.iOS加固保护原理 1.字符串混淆 2.类名.方法名混淆 3.程序结构混淆加密 4.反调试.反注入等一些主动保护策略 二 代码混淆步骤 1. 选择要混淆保护的ipa文件 2. 选择要混淆 ...

  2. ipa如何安装到iphone

    ​ Sign In - Apple app管理中心: https://appstoreconnect.apple.com/ apple ID管理中心: Manage your Apple ID 工具只 ...

  3. Google 发布:DevOps 2022现状报告

    在过去的八年中,全球超过 33,000 名专业人士参与了Accelerate State of DevOps 调查,使其成为同类研究中规模最大.运行时间最长的一项.Accelerate State o ...

  4. IIS 设置超时时间

    高级设置 => 限制 => 连接超时(秒),默认120秒,根据实际情况调整

  5. pytest参数化及应用

    Pytest 安装pytest #安装pytest pip install pytest #检查是否安装 pytest --version 创建第一个测试 def func(x): return x ...

  6. UVA - 1594 :Ducci Sequence (set应用)

    给定n元组(a1,a2,...,an),ai均为整数,得到下一个序列为(|a1-a2|,|a2-a3|,...,|an-a1|),如此循环下去,必定会出现全零序列或重复序列. 现要求判断给定序列是全零 ...

  7. Codeforces Round #722 (Div. 2) A~D题解

    补题链接:Here 1529A. Eshag Loves Big Arrays [题意描述] 给定一个长度为 \(n\) 的正整数数组 \(a\) ,现在可执行若干次操作(可为 \(0\)) 具体操作 ...

  8. 勇者游戏(巴什博弈)- HDU 1846

    博弈算法中比较经典的一个博弈问题是巴什博奕,巴什博弈是这样的: 有一堆物品,数量为n,两个人轮流取,规定每次最多取m个,最少取1个. 我们定义先取者为F(first),后取者为S(second) 网上 ...

  9. vue 文件路径获取文件名

    例如: url 是//resource//20220819//kfz//调试.zip转换后结果为 调试.zip//文件路径获取文件名 getFileName(url) { let name = &qu ...

  10. C语言哈希表uthash的使用方法详解(附下载链接)

    uthash简介   由于C语言本身不存在哈希,但是当需要使用哈希表的时候自己构建哈希会异常复杂.因此,我们可以调用开源的第三方头文件,这只是一个头文件:uthash.h.我们需要做的就是将头文件复制 ...