I have a controller in C# that invokes a class, which in turn makes HTTP requests and returns its response, according to the code sequence below:
I added the following line in Program.cs:
builder.Services.AddHttpClient();
I created a class that receives the controller invocation and makes the HTTP request to the external website.
public class Users
{
public async Task<string> GetUsers(HttpClient _httpClient )
{
var request = new HttpRequestMessage(new HttpMethod("get"), "https://gorest.co.in/public/v2/users");
var res = await _httpClient.SendAsync(request);
var content = await res.Content.ReadAsStringAsync();
return content;
}
}
I created a controller to receive my HTTP requests, and this controller instantiates a client through the IHttpClientFactory, with the aim of avoiding exhaustion of HTTP sockets...
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IHttpClientFactory _client;
public UsersController(IHttpClientFactory client)
{
_client = client;
}
public class UsersModel
{
public int id { get; set; }
public string name { get; set; }
public string email { get; set; }
public string gender { get; set; }
public string status { get; set; }
}
[HttpGet("GetUsers")]
public async Task<List<UsersModel>> GetUsers()
{
var myClient = _client.CreateClient();
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<UsersModel>>(await new Users().GetUsers(myClient));
}
}
Ok, the code sequence above does the job correctly, but there is one thing that bothers me a lot, which is this dependency injection and creation of an HTTP client in each controller that calls this class.
I would like to create a class that accepts being invoked by the controller, but this class itself creates its HTTP client, without it having to be passed as a parameter by the controller...
I tried something like this: I modified my controller to no longer have dependency injection, but just invoke the class:
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
public class UsersModel
{
public int id { get; set; }
public string name { get; set; }
public string email { get; set; }
public string gender { get; set; }
public string status { get; set; }
}
[HttpGet("GetUsers")]
public async Task<List<UsersModel>> GetUsers()
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<UsersModel>>(await new Users().GetUsers());
}
}
The class, in turn, would be responsible for creating the HTTP client.
public class Users
{
private readonly IHttpClientFactory _client;
public Users(IHttpClientFactory client)
{
_client = client;
}
public async Task<string> GetUsers()
{
var _httpClient = _client.CreateClient();
var request = new HttpRequestMessage(new HttpMethod("get"), "https://gorest.co.in/public/v2/users");
var res = await _httpClient.SendAsync(request);
var content = await res.Content.ReadAsStringAsync();
return content;
}
}
I've seen some people saying that they have to implement a constructor, insert a : base()... but I confess that I'm not at a sufficient level to solve this problem on my own. I would really appreciate it if anyone can help me with this task.

There are many problems with your code:
Usersclass is actually a service, but obviously you did not register your service into DI. This often occurs in Program.cs (or .NET Core 3 and below, in StartUp). And should be like this:Besides, a service class usually have the name convention:
XxxService. And usually has an Interface behind it for best practice of DI. but no big deal for your case.You can directly inject the
HttpClientintoUsers, not the factory. You already have DI, it will handle the instantiation ofHttpClient.After you register your service into DI, you can call it from your Controller:
GetUsersmethod in the service should be like this:Usersservice into the Controller, just like how you inject theHttpClientintoUsers. and no morenew()!Please learn the basis before you contribute code for production.