zoukankan      html  css  js  c++  java
  • WebApi client 的面向切面编程

    .Net的面向切面编程

    .Net的服务端应用AOP很常见,在Asp.net MVC与Asp.net WebApi等新框架里到处都有AOP的影子,我们可以把一个服务方法“切”为很多面,日志面、验证面、请求方式处理、接口业务实现等多个面,有一些面可以使用过滤器特性(FilterAttribute)进行编写,然后很方便和打上特性即可,对于一般的工程师,只需要专注实现接口业务实现。

    在流行SOAP的年代,很少需要一个强悍的Client,而今天restful时代,.net也出了一个HttpClient,可以说是与Asp.net WebApi相配吧,虽然HttpClient相对WebClient在http接口请求有了质的变化,但相比服务端的webApi,AOP的影子都不见了。

    让HttpClient支持AOP

    所谓让HttpClient支持AOP,是指在对HttpClient进行组合封装,基于HttpClient再打造一款客户端框架,将AOP的理念引入到新客户端框架来,我们可以简单分析一下HttpClient请求一个接口要做的基本事情,同时把这些事情“切”为多个面,Http请求大致如下:

    {Method} {Path}?query1={value1}&query2={value2}
    {Header1}
    {Header2}
    
    {body}

    我可以切出几个面:

    1. method与path处理
    2. query参数处理
    3. 请求body内容处理
    4. 发送请求
    5. 回复结果处理

    我们所做的框架,需要把1、2、3、5封装为面,同时调用HttpClient来完成第4个动作。

    AOP基础框架的选择

    可以参考这个博客:NET AOP(一)七种AOP实现方法 

    这里我选择了Castle,Castle可以动态创建接口的实现类并实例化,可以对接口方法调用前进行拦截,并设置返回结果。

    我们可以根据这个拦截功能,收集每个面的配置,组装为http请求消息,然后调用HttpClient为完成发送请求,再让第5个面来进行回复结果处理。基于Castle与HttpClient,我们就可以封装出支持AOP的HttpClient新框架,这里命名为WebApiClient吧。

    WebApiClient设计

    现在,我们的目标是,让调用WebApi与编写WebApi一样,声明接口、参数、返回值,打上请求方法与路径(面)特性、返回结果处理(面)特性、请求内容(面)特性。然后框架帮我们实现并取得实例,然后就可以调用这些接口了。

    Step1:声明接口

    namespace Demo
    {
        [JsonReturn]
        [HttpHost("http://www.mywebapi.com")]
        public interface MyWebApi
        {
            [HttpGet("/webapi/{type}/about")] // GET webapi/typeValue/about
            Task<ApiResult<string>> GetAboutAsync(string type);
    
    
            [HttpGet("/webapi/user")]  // GET webapi/user?userName=aa&nickName=bb&&BeginTime=cc&EndTime=dd
            Task<ApiResult<UserInfo>> GetUserAsync(string userName, string nickName, TimeFilter timeFilter);
    
    
            [HttpPut("/webapi/user")] // PUT webapi/user
            Task<ApiResult<bool>> UpdateUserAsync([JsonContent] UserInfo loginInfo);
    
    
            [HttpDelete("/webapi/user")] // DELETE  webapi/user?id=idValue
            Task<ApiResult<bool>> DeleteUserAsync(string id);
    
    
            [HttpDelete("/webapi/user/{id}")] // DELETE  webapi/user/idValue
            Task<ApiResult<bool>> DeleteUser2Async(string id);
        }
    }

    Step2:获取接口实并调用

    namespace Demo
    {
        class Program
        {
            static async void Test()
            {
                var myWebApi = new WebApiClient.HttpApiClient().GetHttpApi<MyWebApi>();
    
                await myWebApi.GetAboutAsync("typeValue");
                await myWebApi.UpdateUserAsync(new UserInfo { UserName = "abc", Password = "123456" });
                await myWebApi.DeleteUser2Async(id: "id001");
            }
    
            static void Main(string[] args)
            {
                Test();
                Console.ReadLine();
            }
        }
    }

    WebApiClient更多的面

    我们可以给框架增加更多的自定义面,比如日志记录、返回结果统一验证等等,这些就不一一介绍,但思想还是一样的。

    WebApiClient开放

    这是一个开放的框架,托管在 https://github.com/xljiulang/WebApiClient

    如果你喜欢,点个星吧。

  • 相关阅读:
    Bean的装配
    什么是脏读,不可重复读,幻读
    MySQL 中的数据类型介绍
    spring事务
    js:防抖动与节流
    React 之容器组件和展示组件相分离解密
    Java 里如何实现线程间通信
    线程之间的通信
    NIO之Buffer的clear()、rewind()、flip()方法的区别
    清空git缓存
  • 原文地址:https://www.cnblogs.com/kewei/p/6646601.html
Copyright © 2011-2022 走看看