Search code examples
c#dependency-injectiondotnet-httpclient

Change BaseUrl of injected HttpClient


I'm currently working on a .NET MAUI app and I'm using DI for working with HttpClient and communicating with my backend.

In the settings, the user can change the URL of the backend, but obviously, the app still requests the old URL, as the Service classes were already injected.

In my MauiProgram.cs I do the following to register the client:

builder.Services.AddHttpClient("APIClient", c => c.BaseAddress = new Uri(Preferences.Get(Constants.SETTING_SERVER, "http://192.168.10.125:5000/")));

builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("APIClient"));

Here is a sample Service class:

public class SampleAPIService
{
    private readonly HttpClient _httpClient;

    public SampleAPIService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    

     // API specific things like GET, POST and so on
     
}

Basically, the change in the Settings does change the return value of Preferences.Get(Constants.SETTING_SERVER). Is there a best practice for my problem? Do I need to inject the Factory rather than the client directly?


Solution

  • As @Artur advised, I made following changes to my code:

    MauiProgram.cs - injecting the Factory rather than a client:

    builder.Services.AddHttpClient("APIClient", c => c.BaseAddress = new Uri(Preferences.Get(Constants.SETTING_SERVER, "http://192.168.10.125:5000/")));
    

    I changed to my Services to look like this (Factory is injected and HttpClient is created on every request):

    public class SampleAPIService
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private HttpClient GetHttpClient() => _httpClientFactory.CreateClient("APIClient"); 
    
        public SampleAPIService(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }
    
        public async Task PostAsJson<T>(string url, T request)
            {
                using var httpClient = GetHttpClient();
                HttpResponseMessage httpResponseMessage = await httpClient.PostAsJsonAsync(url, request);
                if (httpResponseMessage.StatusCode == HttpStatusCode.BadRequest)
                {
                    throw new Exception(await httpResponseMessage.Content.ReadAsStringAsync());
                }
    
                httpResponseMessage.EnsureSuccessStatusCode();
            }   
    
         // more API specific things like GET, POST and so on
         
    }