HTML5技术

我来给.Net设计一款HttpClient - jiulang

字号+ 作者:H5之家 来源:H5之家 2017-09-18 09:01 我要评论( )

1、前言 时间飞快,转眼半年,碌碌无为,眼下就要三十而立,回想三年前的今天,我将NetworkSocket库开放到github,一直在更新与学习,不求有这个库能有多好,只求自己在过程能成长,将领悟到一些思想应用到库里面去。今天,我来给大家介绍半年前在github开放

1、前言

时间飞快,转眼半年,碌碌无为,眼下就要三十而立,回想三年前的今天,我将NetworkSocket库开放到github,一直在更新与学习,不求有这个库能有多好,只求自己在过程能成长,将领悟到一些思想应用到库里面去。今天,我来给大家介绍半年前在github开放的WebApiClient这个库,正如NetworkSocket一样,它正在渐渐从渺小变得强大,从简单变得抽象、易用、可高度扩展,它将带你进入不一个和以往完全不同风格的调用http接口的世界。

 

2、编程风格 2.1传统调用风格

一般的,我们需要new 一个HttpClient实例,然后准备请求url、请求body的HttpContent,然后发送,等待接收,解析回复内容.....

这些都是需要一行一行代码来实现,代码里不仅表现了“做什么(What)”,而且更多表现出“如何(How)”完成工作这样的实现细节,大概想想代码像下面:

更新用户信息 /// 使用application/json提交 Task<UserInfo> UpdateAsync(UserInfo user) { var httpClient = new HttpClient(); var serializer = new JavaScriptSerializer(); var json = serializer.Serialize(user); ); ; var response = await httpClient.PostAsync(url, content); var resJson = await response.Content.ReadAsStringAsync(); var resUser = serializer.Deserialize<UserInfo>(resJson); return resUser; }

传统What How思想代码

服务端任何接口的小变化,都直接影响到我们接口调用的某行具体代码,如果有100个接口,这代码的维护也不小。

2.2WebApiClient风格

WebApiClient的设计可以解放使用者的劳动力,只需要使用者根据http接口来定义一份.Net的interface,在接口里描述你想要什么(what i wan),但不需要实现这份interface(how it do),大概如下:

[HttpHost()] public interface UserApi { [HttpPost()] Task<UserInfo> UpdateWithJsonAsync([JsonContent] UserInfo user); }

那么,接口的实现者给谁来完成呢?给WebApiClient来完成,它很聪明,知道你想要什么,这个正像我们写一条sql:select * from table一样,只有what,没有how。

 

 

3、使用层设计 3.1接口与服务端设计一致

使用者编写的interface,可以与服务端接近完全一致,在编写接口或文档对照方面相当容易。

3.2使用Attribute标记描述“干什么”

上面的[HttpPost]和[JsonContent],用来标记是干什么(不是怎么干)

3.3没有了,只剩下调用接口了

var userApi = new HttpApiClient().Implement<UserApi>(); var resUser = await userApi.UpdateWithJsonAsync(user);

 

 

4、架构层设计

使用Castle来动态实现interface的实例,并获得实例方法调用的拦截,在拦截层,一一调用与方法相关标记的Atribute,Attribute是真正的逻辑实现者,每个Attribute只关注自己应该做什么。

4.1、ApiActionContext

ApiActionContext用于描述接口的详细信息以及接口周边的其它信息,在拦截interface的实例某方法之后,都生成一份ApiActionContext实例,但实例的很多属性是缓存中获取的,任何特性在执行的时候,都可以访问和修改这个ApiActionContext。

4.2、Attribute标记分类

1、IHttpActionAttribute (ApiActionContext)         // 与Api方法相关

2、IApiParameterAttribute (ApiActionContext)    // 与 api参数相关

3、IApiActionFilterAttribute (ApiActionContext)   // 与Api请求前后有关

4、IApiReturnAttribute (ApiActionContext)          // 与api返回值相关

这4个Attribute接口有着各自的职责,前三者一个共同的目标:构造和影响一个请求内容对象HttpRequestMessage,第4个的目标是:从回复的HttpResponseMessage中得到接口的返回值

4.3 Attribute的执行

在拦截器里,按照IApiActionAttribute > IApiParameterAttribute > IApiActionFilterAttribute > IApiReturnAttribute的顺序,将与方法的所有特性都执行,就可以完成接口的调用,大概实现如下:

异步执行api Task<object> ExecuteInternalAsync(ApiActionContext context) { var apiAction = context.ApiActionDescriptor; foreach (var actionAttribute in apiAction.Attributes) { await actionAttribute.BeforeRequestAsync(context); } foreach (var parameter in apiAction.Parameters) { foreach (var parameterAttribute in parameter.Attributes) { await parameterAttribute.BeforeRequestAsync(context, parameter); } } foreach (var filter in apiAction.Filters) { await filter.OnBeginRequestAsync(context); } httpClient = context.HttpClientContext.HttpClient; context.ResponseMessage = await httpClient.SendAsync(context.RequestMessage); foreach (var filter in apiAction.Filters) { await filter.OnEndRequestAsync(context); } return await apiAction.Return.Attribute.GetTaskResult(context); }

 

5、支持的功能特性 5.1方法或接口级特性

绝对主机域名:[HttpHost]

请求方式与路径:[HttpGet]、[HttpPost]、[HttpDelete]、[HttpPut]、[HttpHead]和[HttpOptions]

代理:[Proxy]

请求头:[Header]

返回值:[AutoReturn]、[JsonReturn]、[XmlReturn]

使用者可以自己扩充更多特性。

5.2 参数级特性

路径或query:[PathQuery]、[Url]

请求头:[Header]

请求Body:[HttpContent]、[JsonContent]、[XmlContent]、[FormContent]、[MulitpartConten]

使用者可以自己扩充更多特性。

5.3特殊参数类型

MulitpartFile类(表单文件)、Url类(请求地址)、Proxy类 (请求代理)

这些特殊参数类型在参数里,可以是本类型或本类型的集合,都会被执行

使用者可以自己扩充更多的特殊参数类型。

 

6、扩展能力 6.1 扩展特性

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

    ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

    2017-09-15 17:05

  • ASP.NET Core 运行原理解剖[5]:Authentication - 雨の夜

    ASP.NET Core 运行原理解剖[5]:Authentication - 雨の夜

    2017-09-11 11:16

  • 【ASP.NET MVC】View与Controller之间传递数据 - Alan_beijing

    【ASP.NET MVC】View与Controller之间传递数据 - Alan_beijing

    2017-09-10 08:02

  • .NET Core多平台开发体验[4]: Docker - Artech

    .NET Core多平台开发体验[4]: Docker - Artech

    2017-09-07 11:57

网友点评
4