With IHttpClientFactory, you can create HttpClient instances seamlessly without having to manually manage their lifecycles.

When developing applications using ASP.Net Core, you may often need to call WebAPI methods via HttpClient to check that the endpoints are working properly. To do this, you usually need to instantiate HttpClient and use that instance to call your methods. However, using HttpClient directly has some disadvantages, mainly related to manually managing the life cycle of instances.

You can avoid these problems by creating an HttpClient using IHttpClientFactory. IHttpClientFactory is in. Net Core 2.1, which provides a Core function for naming, configuring, and creating HttpClient instances, and automatically manages instance pooling and lifecycle.

Let’s take a closer look at the HttpClient and IHttpClientFactory code, as well as the concepts designed. To use the provided code, you need to have Visual Studio 2019 installed.

Create an ASP.NET Core MVC project in Visual Studio 2019

Assuming you have Visual Studio 2019 installed on your system, follow the steps listed below to create a new ASP.NET Core project.

1. Start the Visual Studio IDE.

2. Click Create New Project.

3. In the create new project window, select ASP.NET Core Web application from the list of templates.

4. Click Next.

5. In the Configure New Project window, specify the name and location of the new project.

6. You can select the Place solution and project in the same directory check box.

7. Click Create.

8. In the Create a New ASP.NET Core Web Application window, select. NET Core as the runtime, then select ASP.NET Core as the runtime. NET Core 3.1(or later).

9. Select “Web Application (Model-View-Controller)” as the project template to create a new ASP.NET Core MVC Application.

10. Make sure the check boxes “Enable Docker support” and “Configure HTTPS” are not checked, as we will not use these features here.

11. Make sure authentication is set to “no authentication” because we don’t use authentication either.

12. Click Create.

Follow these steps to create a new ASP.NET Core MVC application. In the new project, create a new API Controller and save it with the default name, ValuesController. We will use this project in the next section.

Challenge the HttpClient

Although HttpClient does not directly implement the IDisposable interface, it extends System.Net.Http. HttpMessageInvoker, this class implements IDisposable. However, when using HttpClient instances, you should not manually release them. Although it is possible to call the Dispose method on an HttpClient instance, it is not recommended.

How do you do that? One option is to make HttpClient static, or wrap a non-static instance of HttpClient in a custom class and make it a singleton class. But a better alternative is to use IHttpClientFactory to generate an instance of HttpClient and then use that instance to invoke the action method.

IHttpClientFactory and HttpClientFactory

IHttpClientFactory is an interface implemented by the DefaultHttpClientFactory class, which is a factory pattern. DefaultHttpClientFactory implements IHttpClientFactory and IHttpMessageHandlerFactory interface. IHttpClientFactory provides ASP.NET Core with excellent built-in support for creating, caching, and handling HttpClient instances.

Note that HttpClientFactory is just a helper class for creating an HttpClient instance that uses the provided handler configuration. This class has the following methods:

Create(DelegatingHandler[])
Create(HttpMessageHandler,DelegatingHandler[])
CreatePipeline(HttpMessageHandler,IEnumerable<DelegatingHandler>)
Copy the code

The Create method of the overloaded HttpClientFactory class looks like this:

public static HttpClient Create(params DelegatingHandler[] handlers) { return Create(new HttpClientHandler(), handlers);  } public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers) { HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers); return new HttpClient(pipeline); }Copy the code

The HttpClientFactory and IHttpClientFactory were introduced to better manage the lifecycle of HttpMessageHandler instances.

Why use IHttpClientFactory?

When you release the HttpClient instance, the connection will remain open for up to 4 minutes. In addition, there is a limit to the number of sockets that can be opened at any one time — you can’t open too many sockets at once. Therefore, it is possible to run out of sockets when using too many HttpClient instances.

That’s what IHttpClientFactory is all about. You can avoid HttpClient’s problems by using IHttpClientFactory to create an instance of HttpClient that calls HTTP API methods. The main goal of implementing IHttpClientFactory in ASP.NET Core is to ensure that HttpClient instances are created using factory mode without running out of sockets.

Register an IHttpClientFactory instance in ASP.NET Core

You can register an instance of the IHttpClientFactory type in the Startup class’s ConfigureServices method by calling the AddHttpClient extension on the IServiceCollection instance as follows:

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllersWithViews();
   services.AddHttpClient();
}
Copy the code

Inject the IHttpClientFactory instance into the controller

The IHttpClientFactory instance can be injected into the controller with the following code:

public class HomeController : Controller { private IHttpClientFactory _httpClientFactory; private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger, IHttpClientFactory httpClientFactory) { _logger = logger; _httpClientFactory = httpClientFactory; }}Copy the code

Call HttpClient in Action

To create an HttpClient using IHttpClientFactory, call the CreateClient method. Once the HttpClient instance is available, you can use the following code in the Index method of the HomeController class to call the ValuesController class Get method.

public async Task<IActionResult> Index()
{
   HttpClient httpClient = _httpClientFactory.CreateClient();
   httpClient.BaseAddress = new Uri("http://localhost:1810/");
   var response = await httpClient.GetAsync("/api/values");
   string str = await response.Content.ReadAsStringAsync();
   List<string> data = JsonSerializer.Deserialize<List<string>>(str);
   return View(data);
}
Copy the code

Create and manage HttpClient instances in ASP.NET Core using IHttpClientFactory

There are several ways to use IHttpClientFactory in your application. This includes using the IHttpClientFactory directly, using the named client, and the type client.

The basic or general usage pattern, which is to use the IHttpClientFactory directly, was discussed in the previous section. Please refer to the section “Registering an IHttpClientFactory Instance”, which discusses how to register an HttpClient instance.

If you want to use an instance of HttpClient with a different configuration, the following is a good option. The following code snippet shows how.

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", "This is a test user agent");
});
Copy the code

The second approach is to use a custom class wrapped around an HttpClient instance that encapsulates the logic for calling all endpoints over the HTTP protocol. The following code snippet shows how to define a custom HttpClient class.

public class ProductService : IProductService { private IHttpClientFactory _httpClientFactory; private readonly HttpClient _httpClient; private readonly string _baseUrl = "http://localhost:1810/"; public ProductService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<Catalog> GetAllProducts() { _httpClient = _httpClientFactory.CreateClient(); _httpClient.BaseAddress = new Uri(_baseUrl); var uri = "/api/products"; var result = await _httpClient.GetStringAsync(uri); return JsonConvert.DeserializeObject<Product>(result); }}Copy the code

Register a custom client with the following code:

services.AddHttpClient<IProductService, ProductService>();
Copy the code

Add MessageHandler to the named pipe

MessageHandler is an extension of the HttpMessageHandler class that accepts HTTP requests and returns HTTP responses. If you want to build your own MessageHandler, you should create a class that inherits DelegatingHandler.

You can add HttpMessageHandler to the request processing pipeline. You can add HttpMessageHandler to the pipeline using the following code in the ConfigureServices method of the Startup class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient("github", c =>
    {
        c.BaseAddress = new Uri("https://api.github.com/");
    })
    .AddHttpMessageHandler<DemoHandler>();
    services.AddTransient<DemoHandler>();
}
Copy the code

IHttpClientFactory is a factory class that has been available since.net Core 2.1. If you use IHttpClientFactory to create an HttpClient instance, the pooling and lifecycle of the underlying HttpClientMessagehandler instance is automatically managed. IHttpClientFactory also handles common issues such as logging.

Welcome to pay attention to my public number – code non translation station, if you have a favorite foreign language technical articles, you can recommend to me through the public number message.