幾種使用IHttpClientFactory方法
微軟在.NET Framework 4.5的時候推出HttpClient,以取代原本的WebClient,但是卻有一些連線端耗盡及DNS異動問題。所以微軟又推出了HttpClientFactory來改善這些情況。
關於HttpClient效能議題及HttpClinetFactory介紹,網上已有許多說明,這邊就僅純記錄官方HttpClientFactory使用方法,再補充附加參數的方法
環境
直接使用HttpClientFactory
無論使用何種方式,都必須在Startup.cs
中的ConfigureServices
方法中註冊HttpClient
1
2
3
4
5
6
|
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddRazorPages();
}
|
在要使用的類別上,使用相依性插入 (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
|
public class LineService : ILineService
{
private readonly IHttpClientFactory _httpClientFactory;
public LineService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task PushMessage()
{
// 建立 HttpClient 實例
var httpClient = _httpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri("https://api.line.me");
httpClient.DefaultRequestHeaders.Add("authorization", "Bearer {CannelAccessToken}");
var message = "Fake Message Object";
var json = JsonConvert.SerializeObject(message);
HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");
await httpClient.PostAsync("/v2/bot/message/push", contentPost);
}
}
|
具名用戶端(Named Clients)
在Startup.cs
註冊通用基礎設定值
1
2
3
4
5
6
7
8
9
10
11
|
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("Line", c =>
{
c.BaseAddress = new Uri("https://api.line.me");
// ChannelAccessToken 請自行替換
c.DefaultRequestHeaders.Add("authorization", "{ChannelAccessToken}");
});
services.AddRazorPages();
}
|
使用定義的名稱建立 HttpClient 實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class LineService : ILineService
{
private readonly IHttpClientFactory _httpClientFactory;
public LineService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task PushMessage()
{
// 使用定義的名稱建立 HttpClient 實例
var httpClient = _httpClientFactory.CreateClient("Line");
var message = "Fake Message Object";
var json = JsonConvert.SerializeObject(message);
HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");
await httpClient.PostAsync("/v2/bot/message/push", contentPost);
}
}
|
具型別用戶端(Typed Client)
使用Typed Client方法,就是在類別中使用HttpClient,而非IHttpClientFactory介面,這時候預設值有兩種方法設置。
在自訂類別中的建構子設定預設值
1
2
3
4
5
6
|
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<ILineService, LineService>();
services.AddRazorPages();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class LineService : ILineService
{
private readonly HttpClient _httpClient;
public LineService(HttpClient httpClient)
{
httpClient.BaseAddress = new Uri("https://api.line.me");
httpClient.DefaultRequestHeaders.Add("authorization", "Bearer {CannelAccessToken}");
_httpClient = httpClient;
}
public async Task PushMessage()
{
var message = "Fake Message Object";
var json = JsonConvert.SerializeObject(message);
HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");
await _httpClient.PostAsync("/v2/bot/message/push", contentPost);
}
}
|
1
2
3
4
5
6
7
8
9
10
|
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<ILineService, LineService>(x =>
{
x.BaseAddress = new Uri("https://api.line.me");
x.DefaultRequestHeaders.Add("authorization", "Bearer {CannelAccessToken}");
});
services.AddRazorPages();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class LineService : ILineService
{
private readonly HttpClient _httpClient;
public LineService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task PushMessage()
{
var message = "Fake Message Object";
var json = JsonConvert.SerializeObject(message);
HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");
await _httpClient.PostAsync("/v2/bot/message/push", contentPost);
}
}
|
參考
在 ASP.NET Core 中使用 IHttpClientFactory 發出 HTTP 要求
https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#named-clients