Bootstrap
Microsoft 在.Net Framework 4.5中引入了HttpClient,并且是在.NET服务器端代码中使用Web API的最常用方法。但它有一些严重的问题,如释放HttpClient对象不立即关闭套接字,太多实例影响性能和单个的HttpClient或共享HttpClient实例不尊重DNS生存时间(TTL)设置。HttpClientFactory解决了所有这些问题。它是ASP.NET Core 2.1的最新功能之一。本文主要介绍在ASP.NET Core 2.1中使用HTTPClientFactory的3种方法。

1、直接使用HttpClientFactory

1)在Startup.csConfigureService方法中注册HttpClient,代码如下,

services.AddHttpClient();

2)在API controller(控制器)中调用代码

public class ValuesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;
  
    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }
  
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = _httpClientFactory.CreateClient();
        client.BaseAddress = new Uri("http://api.github.com");
        string result = await client.GetStringAsync("/");
        return Ok(result);
    }
}

2、通过HttpClient名字调用HttpClientFactory

如果需要进行多个请求并且较复杂,则可以使用这种方式,很方便。

1)将HttpClient请求命名,代码如下,

services.AddHttpClient();
services.AddHttpClient("github", c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

2)在API controller(控制器)中调用命名的HttpClient

public class ValuesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;
  
    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }
  
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = _httpClientFactory.CreateClient("github");
        string result = await client.GetStringAsync("/");
        return Ok(result);
    }
}

3、使用自定义类执行HttpClientFactory请求

1)自定义HttpClientFactory请求类

public class GitHubClient
{
    public HttpClient Client { get; private set; }
    
    public GitHubClient(HttpClient httpClient)
    {
        httpClient.BaseAddress = new Uri("https://api.github.com/");
        httpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
        httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
        Client = httpClient;
    }
}

2)在Startup.csConfigureService方法中注册GitHubClient,代码如下,

services.AddHttpClient<GitHubClient>();

3)在API controller(控制器)中调用代码

public class ValuesController : Controller
{
    private readonly GitHubClient _gitHubClient;;
  
    public ValuesController(GitHubClient gitHubClient)
    {
        _gitHubClient = gitHubClient;
    }
  
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        string result = await _gitHubClient.client.GetStringAsync("/");
        return Ok(result);
    }
}

4、完全封装HttpClient可以使用下面方法

1)自定义HttpClientFactory请求类

public interface IGitHubClient
{
    Task<string> GetData();
}
 
public class GitHubClient : IGitHubClient
{
    private readonly HttpClient _client;
 
    public GitHubClient(HttpClient httpClient)
    {
        httpClient.BaseAddress = new Uri("https://api.github.com/");
        httpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
        httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
        _client = httpClient;
    }
 
    public async Task<string> GetData()
    {
        return await _client.GetStringAsync("/");
    }
}

2)在Startup.csConfigureService方法中注册GitHubClient,代码如下,

services.AddHttpClient<IGitHubClient, GitHubClient>();

3)在API controller(控制器)中调用代码

public class ValuesController : Controller
{
    private readonly IGitHubClient _gitHubClient;;
     
    public ValuesController(IGitHubClient gitHubClient)
    {
        _gitHubClient = gitHubClient;
    }
     
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        string result = await _gitHubClient.GetData();
        return Ok(result);
    }
}

注意:三种方法都必须在Startup.csConfigureService方法中注册HttpClient