.net core 动态代理
warning:
这篇文章距离上次修改已过759天,其中的内容可能已经有所变动。
动态代理简介
对于某一个实例,对其行为进行无感知的包装。从而达到AOP
的目的。
目前想到一个比较典型的例子就是向外部发送请求,对接第三方接口时,大多数都是如下情况:
- 像外部指定接口发送请求
- 接收返回数据
- 处理异常
- 处理返回数据
- 返回给业务系统
这中间其实是一个很通用的操作,非常标准化的流程。但是很多情况下都要重复的去实现,因此想将这部分做一个代理,并且是一种完全依赖接口的代理(无需实现接口)。
示例(设想)
在实现前,我们先来假设一下最终使用时的效果,这只是一个粗糙的想法,后面来慢慢完善。
定义:
[Proxy(typeof(HttpRequestProxy))]
[RequestHost("https://example.com/api")]
public interface OtherSystem
{
[HttpGet]
[Route("userinfo")]
UserInfoResponse GetUserInfo(long id);
}
使用(基于IOC
):
public class UserService
{
private readonly OtherSystem otherSystem;
public UserService(OtherSystem otherSystem)
{
this.otherSystem = otherSystem;
}
public UserInfo GetUserInfo(long id)
{
return this.otherSystem.GetUserInfo(id);
}
}
这其中还可以直接使用原生中已有的Attribute
,避免重复造轮子,也可以语义化,并且利用现有特性来完成功能。
技术分析
目前代理实现分为几种:
- 原生
DispatchProxy
- 第三方
Castle DynamicProxy
Feign
(Java, spring cloud openFeign),声明式客户端
DispatchProxy
基于DispatchProxy
可以实现核心的几个功能:
- 解析
interface
的注解,获取请求信息。 - 解析
method
的注解,获取具体请求路径,参数,返回值类型等。 - 拦截调用,不调用具体实例。
HttpClient
httpClient
本身支持多配置,并且能通过HttpClientFactory
进行实例化,相当于自带管理了。
services.AddHttpClient("wechat", c =>
{
c.BaseAddress = new Uri("https://example.com/api")
})
实例化:
public class TestService
{
private readonly IHttpClientFactory httpClientFactory;
public TestService(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public void test()
{
var client = httpClientFactory.CreateClient("wechat");
}
}
实现
在实现之前先指定一下规则,确定下来使用。
注解
- RemoteClient(string name),用于接口上,扫描到此类会被自动注册并代理
- HttpMethodBase,用于方法上,这里沿用
Mvc
中的标签,支持路由模板 - RequestRoute(string name),用于指定参数去向,下同
- ReqeustQuery(string name)
- RequestBody(string name)
- RequestHeader(string name)
- RequestForm(string name)
评论已关闭