Dadas las siguientes clases:
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; } }y la siguiente configuración:
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"); });Cuando intento resolver ServiceA y ServiceB, ambos obtienen un HttpClient con la misma URL.
¿Cómo cambio el registro en DI, para que cada servicio obtenga el HttpClient correcto inyectado?
AIT
/Søren
Preferiría hacer algo como esto.
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; } }Y en ConfigureService.
services.AddHttpClient<ServiceA>().ConfigureHttpClient(client => { client.BaseAddress = new Uri("http://domainA"); }); services.AddHttpClient<ServiceB>().ConfigureHttpClient(client => { client.BaseAddress = new Uri("http://domainB"); });Nota :
En tu caso, dos cosas son problemáticas.
AddSingleton para ServiceA y ServiceBAddHttpClient<HttpHelper> es un problema, ya que se convierte en singleton y solo se inicia uno.Otra forma es configurarlo por nombre de fábrica:
//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); });Un problema con este enfoque es que necesita definir explícitamente la resolución para el Servicio A y B.
Terminé haciendo esto:
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"); });parece funcionar como yo quería....