Given the following classes:
public class HttpHelper
{
private readonly HttpClient client;
public HttpHelper(HttpClient client)
{
this.client = client;
}
}
public class ServiceA
{
private readonly HttpHelper helper;
public ServiceA(HttpHelper helper)
{
this.helper = helper;
}
}
public class ServiceB
{
private readonly HttpHelper helper;
public ServiceB(HttpHelper helper)
{
this.helper = helper;
}
}
and the following setup:
sc.AddSingleton<ServiceA>()
.AddHttpClient<HttpHelper>()
.ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri("http://domainA"); });
sc.AddSingleton<ServiceB>()
.AddHttpClient<HttpHelper>()
.ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri("http://domainB"); });
When I try to resolve ServiceA and ServiceB they both get an HttpClient with the same URL.
How do I change the registration in DI, so that each services get the correct HttpClient injected?
TIA
/Søren
I would rather do something like this.
public class ServiceA
{
private readonly HttpClient httpClient;
public ServiceA(HttpClient httpClient)
{
this.httpClient = httpClient;
}
}
public class ServiceB
{
private readonly HttpClient httpClient;
public ServiceB(HttpClient httpClient)
{
this.httpClient = httpClient;
}
}
And in ConfigureService.
services.AddHttpClient<ServiceA>().ConfigureHttpClient(client =>
{
client.BaseAddress = new Uri("http://domainA");
});
services.AddHttpClient<ServiceB>().ConfigureHttpClient(client =>
{
client.BaseAddress = new Uri("http://domainB");
});
Note :
In your case two things is problamatic.
AddSingleton for ServiceA and ServiceBAddHttpClient<HttpHelper> is issue as it become singleton and only one get initiated.Another way is to set it by factory name:
//configure your clients services.AddHttpClient("clientName1", client => { //configure }); services.AddHttpClient("clientName2", client => { //configure }); //configure your services services.AddScoped<ServiceA>(sp => { var client = sp.GetRequiredService<IHttpClientFactory>() .CreateClient("clientName1"); return new ServiceA(client); }); services.AddScoped<ServiceB>(sp => { var client = sp.GetRequiredService<IHttpClientFactory>() .CreateClient("clientName2"); return new ServiceB(client); });One problem with this approach is that you need to explicitly define the resolution for Service A and B.
I ended up doing this:
sc.AddSingleton(sp =>
{
var client = sp.GetRequiredService<IHttpClientFactory>()
.CreateClient(typeof(ServiceA).FullName);
return new ServiceA(new HttpHelper(client));
})
.AddHttpClient<HttpHelper>(typeof(ServiceA).FullName)
.ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri("http://domainA"); });
sc.AddSingleton(sp =>
{
var client = sp.GetRequiredService<IHttpClientFactory>()
.CreateClient(typeof(ServiceB).FullName);
return new ServiceB(new HttpHelper(client));
})
.AddHttpClient<HttpHelper>(typeof(ServiceB).FullName)
.ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri("http://domainB"); });
seems to work the way I wnated....