HttpClient vs IHttpClientFactory in .Net

Çağlar Can SARIKAYA
2 min readFeb 24, 2024

--

Hi everyone, I found something interesting and I would like to share this with you. I was reviewing my codes on startup and I saw one of them is interesting on dependency injection. It added like that

services.AddHttpClient<IGoogleNewsRssService, GoogleNewsRssService>();

but I was expecting AddScoped or any other method. So I researched that.

Let's go to understand HttpClient and IHttpClientFactory.

In many applications, we need to send HTTP requests. HttpClient Class is helping us to do this. But creating many of HttpClient objects also creates problems in our system. The best practice is to reuse HTTPClient. If we create new ones, it causes a memory leak, and also the ports close immediately even when using that class by using scopes. Also, each HTTP client class creates its own HttpMessageHandler object so this will create the memory leak.

But if we use the IHttpClientFactory class we can solve all these problems, when closed it will close but still the port is open, but if you create it again it will not allocate another port, it will use the old one, etc.

You need to add this class to your di, otherwise, you get an unresolving error.

services.AddHttpClient();
services.AddScoped<IMyService, MyService>();

If you want to use IHttpClientFactory in your service, you have to add this to di in your service.

public class MyService : IMyService
{
private readonly IHttpClientFactory _httpClientFactory;

public MyService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}

public async Task<string> GetDataAsync(string url)
{
var client = _httpClientFactory.CreateClient();
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();

return await response.Content.ReadAsStringAsync();
}
}

If the service has too many dependencies like db, like other services you should this method, but if you use that service heavily for creating httprequests, you have other options.

AddHttpClient<IMyService, MyService>()

You can save your service like that, and it will create automatically an HTTP client in your service, but you need to define a HttpClient on its constructor.

public class MyService : IMyService
{
private readonly HttpClient _httpClient;
private readonly MyDbContext _dbContext;

public MyService(HttpClient httpClient, MyDbContext dbContext)
{
_httpClient = httpClient;
_dbContext = dbContext;
}

public async Task FetchDataAndSaveAsync(string requestUri)
{
// Web API'den veri çekme
var responseString = await _httpClient.GetStringAsync(requestUri);

// Veriyi işleme ve veritabanına kaydetme
var data = ProcessData(responseString);
await _dbContext.MyData.AddAsync(data);
await _dbContext.SaveChangesAsync();
}

// Veriyi işleme metodunuz burada olabilir
private MyData ProcessData(string responseString)
{
// Veriyi işleyip MyData nesnesi olarak döndürme
return new MyData();
}
}

So it is what it is. You know now, if you see any

services.AddHttpClient<IGoogleNewsRssService, GoogleNewsRssService>();
//or
services.AddScoped<IGoogleService, GoogleService>();

You know that one is creates a http client by using Ihttpclientfactory and put into the di.

--

--