net Core is implemented using IHttpClientFactory requests

  • 2021-11-13 07:08:46
  • OfStack

Introduction: This article has been added to the Dawn Micro-service Tour. Now I am trying the micro-service architecture, and I am learning while doing the project to quickly enter the state. Of course, in the process of learning, I will share my knowledge.

1. Why not use HttpClient

1. When HttPClient is used up, it will not be closed immediately. When opening the network connection, it will occupy the underlying socket resource, but when HttpClient calls its own Dispose method, it cannot release the resource immediately

2. If you use HttpClient frequently, it will consume a lot to open and close links frequently.

2. Solutions

1. We can extend the lifecycle of HttpClient, such as creating a static object for it


private static HttpClient Client = new HttpClient();

2. Or use singleton mode. As for which singleton mode you use, it depends on yourself, so I won't go into details here. Because it doesn't feel very comfortable

3. HttpClientFactory

1. HttpClientFactory, introduced after. NET Core version 2.1, addresses all the pain points of HttpClient. With HttpClientFactory, we don't need to care how to create HttpClient and how to release it. It allows you to create business-specific HttpClient, and it can be very friendly in combination with the DI container, more flexible.

2. HttpClient created by HttpClientFactory, that is, HttpClientHandler, but these HttpClient are put into the "pool", and the factory will automatically judge whether to build or reuse every time create is created. (The default lifecycle is 2min, and the default lifecycle can be modified)


  // Modify the default lifecycle 
  services.AddHttpClient()
 .SetHandlerLifetime(TimeSpan.FromMinutes(5));

4. Use of HttpClientFactory

1. The first mode of use

Register in Startup. cs


 // Registration http Request service 
 services.AddHttpClient();

2. Use in Httphelper request helper class


/// <summary>
    ///  Injection http Request 
    /// </summary>
    private readonly IHttpClientFactory httpClientFactory;
    public HttpHelp(IHttpClientFactory _httpClientFactory)
    {
      httpClientFactory = _httpClientFactory;
    }

    // <summary>
    // Get Request data 
    // <para> Eventually with url Parameter is submitted in the way of </para>
    // </summary>
    // <param name="parameters"> Parameter dictionary , Can be null </param>
    // <param name="requestUri"> For example /api/Files/UploadFile</param>
    // <returns></returns>
    public async Task<string> Get(Dictionary<string, string> parameters, string requestUri, string token)
    {
      // Get the request object from the factory 
      var client = httpClientFactory.CreateClient();
      // Add a request header 
      if (!string.IsNullOrWhiteSpace(token))
      {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
      }
      client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
      // Splice address 
      if (parameters != null)
      {
        var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value));
        requestUri = string.Concat(requestUri, '?', strParam);
      }
      client.BaseAddress = new Uri(requestUri);
      return client.GetStringAsync(requestUri).Result;
    }

3. Then we can register the opposite class in Startup. cs.

2. Using a named client

1. Register in Startup. cs, which can exist as many as possible. To create name distinction


services.AddHttpClient("github", c =>
{
  c.BaseAddress = new Uri("https://xxxxxxx.com/");
  // Github API versioning
  c.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
  // Github requires a user-agent
  c.DefaultRequestHeaders.Add("Authorization", "asfasfasdsgdsfsdfsdafasfas");
});

2. Use the same way as the above one as long as


/// <summary>
    ///  Injection http Request 
    /// </summary>
    private readonly IHttpClientFactory httpClientFactory;
    public HttpHelp(IHttpClientFactory _httpClientFactory)
    {
      httpClientFactory = _httpClientFactory;
    }

    // <summary>
    // Get Request data 
    // <para> Eventually with url Parameter is submitted in the way of </para>
    // </summary>
    // <param name="parameters"> Parameter dictionary , Can be null </param>
    // <param name="requestUri"> For example /api/Files/UploadFile</param>
    // <returns></returns>
    public async Task<string> Get(Dictionary<string, string> parameters, string requestUri, string token)
    {
      // Get the request object from the factory    Declare which you created 1 A httpClient Client 
      var client = httpClientFactory.CreateClient("github");
      // Add a request header 
      if (!string.IsNullOrWhiteSpace(token))
      {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
      }
      client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
      // Splice address 
      if (parameters != null)
      {
        var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value));
        requestUri = string.Concat(requestUri, '?', strParam);
      }
      client.BaseAddress = new Uri(requestUri);
      return client.GetStringAsync(requestUri).Result;
    }

3. Typed client

1. Create a class


public class HttpClienService
{
  public HttpClient Client { get; }
  public HttpClienService(HttpClient client)
  {
    client.BaseAddress = new Uri("https://xxxx.com/");
    // GitHub API versioning
    client.DefaultRequestHeaders.Add("Authorization",
      "xxxxxxxxxxxx");
    // GitHub requires a user-agent
    client.DefaultRequestHeaders.Add("Content-Type",
      "application/json; charset=utf-8");
    Client = client;
  }

  // The following is to write your own method and call it 
}

2. Register in Startup. cs, which can exist more than one.


services.AddHttpClient<classHttp>();
// After registration, use dependency injection for injection and use. 

Related articles: