Contents

幾種使用IHttpClientFactory方法

幾種使用IHttpClientFactory方法

微軟在.NET Framework 4.5的時候推出HttpClient,以取代原本的WebClient,但是卻有一些連線端耗盡及DNS異動問題。所以微軟又推出了HttpClientFactory來改善這些情況。

關於HttpClient效能議題及HttpClinetFactory介紹,網上已有許多說明,這邊就僅純記錄官方HttpClientFactory使用方法,再補充附加參數的方法

環境

  • .NET Core 3.1

直接使用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);
    }
}

ConfigureServices註冊HttpClient設定

 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