使用方式
IHttpClientFactory有四種模式:
- 基本用法
- 命名客戶端
- 類型化客戶端
- 生成的客戶端
基本用法
在 Startup.ConfigureServices 方法中,通過在 IServiceCollection 上調用 AddHttpClient 擴展方法可以注冊 IHttpClientFactory
1
|
services.AddHttpClient(); |
注冊之后可以像依賴注入DI似得在類中通過構造函數注入形式使用,偽代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class A { private readonly IHttpClientFactory _clientFactory; public A(IHttpClientFactory clientFactory) { _clientFactory = clientFactory; } Public void Use() { var request= new HttpRequestMessage(HttpMethod.Get, "www.baidu.com" ) ; var client = _clientFactory.CreateClient(); var response = await client.SendAsync(request); if (response.IsSuccessStatusCode) { Branches = await response.Content.ReadAsAsync<IEnumerable<GitHubBranch>>(); } else { GetBranchesError = true ; Branches = Array.Empty<GitHubBranch>(); } } } |
命名客戶端
也是在基本用法的基礎上增加配置參數:例如增加一個baidu下的客戶端:
1
2
3
4
5
|
services.AddHttpClient( "baidu" ,c=> { c.BaseAddress = new Uri( "https://api.baidu.com/" ); //其他一些參數 }); |
然后在使用的時候只是需要傳遞客戶端名稱就自動使用baidu這個地址的基礎地址配置:
1
|
var client = _clientFactory.CreateClient( "baidu" ); |
類型化客戶端
說的明白一點就是在使用類的構造函數中可以直接接受HttpClient 類型,不用在使用IHttpClientFactory 接口的CreateClient方法創建,但是首要條件就是要先創建注入類型,然后在ConfigureServices 方法同時注入:
1
|
services.AddHttpClient<classHttp>(); |
注入類型:
1
2
3
4
5
6
7
8
9
10
|
public class classHttp { public HttpClient Client { get ; } public GitHubService(HttpClient client) { client.BaseAddress = new Uri( "https://api.baidu.com/" ); //同ConfigureServices 中一樣設置一些其他參數 Client = client; } } |
生成的客戶端
這個我個人理解為就是配置使用第三方庫,然后可以注入接口類型,接口中可以寫一些方法接口。然后通過接口類直接調用接口。
個人理解:就是類似于一個接口映射,地址映射似得。通過結合第三方庫(官方推薦Refit)實現請求一個地址別名的方式,別名就是指定義的接口。然后別名通過增加特性Get(“路徑”)或者post("路徑)的形式重新指向真實的請求接口地址。通過請求這個本地接口方法實現轉化請求的真實地址。
舉例定義接口:
1
2
3
4
5
|
public interface IHelloClient { [Get( "/MyInterFace" )] Task<Reply> GetMessageAsync(); } |
配置Refit插件:
也是和正常配置類似,在后面增加接口的服務注入。
1
2
3
4
5
6
7
8
9
10
|
public void ConfigureServices(IServiceCollection services) { services.AddHttpClient( "hello" , c => { c.BaseAddress = new Uri( "http://localhost:5000" ); }) .AddTypedClient(c => Refit.RestService.For<IHelloClient>(c)); services.AddMvc(); } |
然后再說接口上面的Get("/MyInterFace")方法;這個我們就不做另一個項目就在當前項目下,所以可以直接就在api項目下創建一個名為MyInterFace的方法。
1
2
3
4
5
6
7
8
9
|
[ApiController] public class TestController : ControllerBase { [HttpGet( "/" )] public async Task<sting> MyInterFace() { return "ceshi" ; } } |
然后就可以使用接口了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[ApiController] public class ValuesController : ControllerBase { private readonly IHelloClient _client; public ValuesController(IHelloClient client) { _client = client; } [HttpGet( "/" )] public async Task<ActionResult<Reply>> Index() { return await _client.GetMessageAsync(); } } |
在這了的_client.GetMessageAsync()方法就是調用了接口方法,看著是調用了GetMessageAsync方法其實是做了映射,映射地址就是上面特性寫的MyInterFace方法。通過斷點也可以驗證此結論。然后不同項目下也是同一個意思,假如我們請求百度的地址:www.baidu.com/api/b這個接口
我們在配置出把請求地址http://localhost:5000改為www.baidu.com/api,然后再把GetMessageAsync方法上面的MyInterFace改為b即可。
出站請求中間件
個人理解為請求返回前處理程序,就是繼承 DelegatingHandler派生類重寫SendAsync 方法。在將請求傳遞至管道中的下一個處理程序之前執行代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ValidateHeaderHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { if (!request.Headers.Contains( "X-API-KEY" )) { return new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent( "You must supply an API key header called X-API-KEY" ) }; } return await base .SendAsync(request, cancellationToken); } } |
然后在ConfigureServices中:
1
2
3
4
5
6
7
|
services.AddTransient<ValidateHeaderHandler>(); //注冊處理程序 services.AddHttpClient( "externalservice" , c => { // Assume this is an "external" service which requires an API KEY c.BaseAddress = new Uri( "https://localhost:5000/" ); }) .AddHttpMessageHandler<ValidateHeaderHandler>();/注入到http請求管道 |
可以同時注冊多個處理程序。
HttpClient和生存周期
每次對 IHttpClientFactory 調用 CreateClient 都會返回一個新 HttpClient 實例。 每個命名的客戶端都具有一個 HttpMessageHandler。 工廠管理 HttpMessageHandler 實例的生存期。
HttpClient實例不是與HttpMessageHandler一起銷毀的,HttpMessageHandler在池中生存,如果生命周期未到不會被銷毀,會被新的HttpClient 實例使用。
處理程序的默認生存周期是2分鐘,可以通過配置修改:
1
2
|
services.AddHttpClient( "extendedhandlerlifetime" ) .SetHandlerLifetime(TimeSpan.FromMinutes(5)); |
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。
原文鏈接:https://www.cnblogs.com/yanbigfeg/p/11509926.html