.Net的面向切面編程
.Net的服務(wù)端應(yīng)用AOP很常見,在Asp.net MVC與Asp.net WebApi等新框架里到處都有AOP的影子,我們可以把一個服務(wù)方法“切”為很多面,日志面、驗(yàn)證面、請求方式處理、接口業(yè)務(wù)實(shí)現(xiàn)等多個面,有一些面可以使用過濾器特性(FilterAttribute)進(jìn)行編寫,然后很方便和打上特性即可,對于一般的工程師,只需要專注實(shí)現(xiàn)接口業(yè)務(wù)實(shí)現(xiàn)。
在流行SOAP的年代,很少需要一個強(qiáng)悍的Client,而今天restful時代,.net也出了一個HttpClient,可以說是與Asp.net WebApi相配吧,雖然HttpClient相對WebClient在http接口請求有了質(zhì)的變化,但相比服務(wù)端的webApi,AOP的影子都不見了。
讓HttpClient支持AOP
所謂讓HttpClient支持AOP,是指在對HttpClient進(jìn)行組合封裝,基于HttpClient再打造一款客戶端框架,將AOP的理念引入到新客戶端框架來,我們可以簡單分析一下HttpClient請求一個接口要做的基本事情,同時把這些事情“切”為多個面,Http請求大致如下:
{Method} {Path}?query1={value1}&query2={value2}
{Header1}
{Header2}
{body}
我可以切出幾個面:
method與path處理
query參數(shù)處理
請求body內(nèi)容處理
發(fā)送請求
回復(fù)結(jié)果處理
我們所做的框架,需要把1、2、3、5封裝為面,同時調(diào)用HttpClient來完成第4個動作。
AOP基礎(chǔ)框架的選擇
可以參考這個博客:NET AOP(一)七種AOP實(shí)現(xiàn)方法
這里我選擇了Castle,Castle可以動態(tài)創(chuàng)建接口的實(shí)現(xiàn)類并實(shí)例化,可以對接口方法調(diào)用前進(jìn)行攔截,并設(shè)置返回結(jié)果。
我們可以根據(jù)這個攔截功能,收集每個面的配置,組裝為http請求消息,然后調(diào)用HttpClient為完成發(fā)送請求,再讓第5個面來進(jìn)行回復(fù)結(jié)果處理?;贑astle與HttpClient,我們就可以封裝出支持AOP的HttpClient新框架,這里命名為WebApiClient吧。
WebApiClient設(shè)計(jì)
現(xiàn)在,我們的目標(biāo)是,讓調(diào)用WebApi與編寫WebApi一樣,聲明接口、參數(shù)、返回值,打上請求方法與路徑(面)特性、返回結(jié)果處理(面)特性、請求內(nèi)容(面)特性。然后框架幫我們實(shí)現(xiàn)并取得實(shí)例,然后就可以調(diào)用這些接口了。
Step1:聲明接口

namespaceDemo
{
[JsonReturn]
[HttpHost("http://www.mywebapi.com")]publicinterfaceMyWebApi
{
[HttpGet("/webapi/{type}/about")]//GET webapi/typeValue/aboutTask> GetAboutAsync(stringtype);
[HttpGet("/webapi/user")]//GET webapi/user?userName=aa&nickName=bb&&BeginTime=cc&EndTime=ddTask> GetUserAsync(stringuserName,stringnickName, TimeFilter timeFilter);
[HttpPut("/webapi/user")]//PUT webapi/userTask>UpdateUserAsync([JsonContent] UserInfo loginInfo);
[HttpDelete("/webapi/user")]//DELETE? webapi/user?id=idValueTask> DeleteUserAsync(stringid);
[HttpDelete("/webapi/user/{id}")]//DELETE? webapi/user/idValueTask> DeleteUser2Async(stringid);
}
}

Step2:獲取接口實(shí)并調(diào)用

namespaceDemo
{classProgram
{staticasyncvoidTest()
{varmyWebApi =newWebApiClient.HttpApiClient().GetHttpApi();awaitmyWebApi.GetAboutAsync("typeValue");awaitmyWebApi.UpdateUserAsync(newUserInfo { UserName ="abc", Password ="123456"});awaitmyWebApi.DeleteUser2Async(id:"id001");
}staticvoidMain(string[] args)? ? ? ? {? ? ? ? ? ? Test();? ? ? ? ? ? Console.ReadLine();? ? ? ? }? ? }}

WebApiClient更多的面
我們可以給框架增加更多的自定義面,比如日志記錄、返回結(jié)果統(tǒng)一驗(yàn)證等等,這些就不一一介紹,但思想還是一樣的。
WebApiClient開放
這是一個開放的框架,托管在https://github.com/xljiulang/WebApiClient
歡迎加入技術(shù)QQ群:364595326