解析不同的HttpClient

Resolving different HttpClient

给出以下 类:

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;
    }
}

以及以下设置:

      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"); });

当我尝试解析 ServiceA 和 ServiceB 时,它们都得到一个具有相同 URL 的 HttpClient。

如何更改 DI 中的注册,以便每个服务都能注入正确的 HttpClient?

TIA

/索伦

我宁愿做这样的事情。

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;
    }
}

并在 ConfigureService 中。

services.AddHttpClient<ServiceA>().ConfigureHttpClient(client =>
{
    client.BaseAddress = new Uri("http://domainA");
});
services.AddHttpClient<ServiceB>().ConfigureHttpClient(client =>
{
    client.BaseAddress = new Uri("http://domainB");
});

注:

在你的情况下,有两件事是有问题的。

  1. AddSingleton 对于 ServiceAServiceB
  2. AddHttpClient<HttpHelper> 是个问题,因为它变成了单例并且只有一个被启动。

另一种方法是通过命名工厂进行配置:

//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);
    });

此方法的一个问题是您明确需要为服务 A 和 B 定义解析器。

我最终这样做了:

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"); });

似乎按照我想的方式工作....