在自定义客户端中使用来自 IHttpClientFactory 的命名 HttpClient

Using named HttpClient from IHttpClientFactory in a custom client

我知道我会因为问这个已经被问过一百万次的问题而被钉在十字架上,我向你保证我已经看过其中的大部分 questions/answers 但我仍然有点卡住了.

这是一个 .NET Standard 2.0 class 库,支持 ASP.NET Core 6 API。

在我的 Program.cs 中,我创建了一个命名的 HttpClient,如下所示:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

我有一个将使用此 HttpClient 的自定义客户端,我在 Program.cs 中创建了一个单例 MyCustomClient 以便我的存储库可以使用它。代码如下。这是我卡住的地方,因为我不确定如何将我命名的 HttpClient 传递给 MyCustomClient.

builder.Services.AddSingleton(new MyCustomClient(???)); // I think I need to pass the HttpClient to my CustomClient here but not sure how

我的 CustomClient 需要使用这个名为 XYZ_Api_ClientHttpClient 来完成它的工作:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(HttpClient client)
   {
       _client = client;
   }

   public async Task<bool> DoSomething()
   {
      var result = await _client.GetAsync();
      return result;
   }
}

所以我不确定如何将这个名为 HttpClient 的文件传递给 Program.cs 中的 MyCustomClient

你可以直接在你的class中注入IHttpClientFactory,然后将命名的HttpClient赋值给一个属性。

注册工厂和您的自定义客户端:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

// no need to pass anything, the previous line registered IHttpClientFactory in the container
builder.Services.AddSingleton<MyCustomClient>();

然后在你身上 class:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(IHttpClientFactory factory)
   {
       _client = factory.CreateClient("XYZ_Api_Client");
   }
   // ...
}

或者,你可以在注册时传递命名实例MyCustomClient

注册工厂和您的自定义客户端:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

// specify the factory for your class 
builder.Services.AddSingleton<MyCustomClient>(sp => 
{
    var factory = sp.GetService<IHttpClientFactory>();
    var httpClient = factory.CreateClient("XYZ_Api_Client");
    
    return new MyCustomClient(httpClient);
});

然后在你身上 class:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(HttpClient client)
   {
       _client = client;
   }
   // ...
}

您也可以这样做:

// register the named client with the name of the class
builder.Services.AddHttpClient("MyCustomClient", config =>
{
    config.BaseAddress = new Uri("https://example.com/api");
});

// no need to specify the name of the client
builder.Services.AddHttpClient<MyCustomClient>();

AddHttpClient<TClient>(IServiceCollection)所做的是

Adds the IHttpClientFactory and related services to the IServiceCollection and configures a binding between the TClient type and a named HttpClient. The client name will be set to the full name of TClient.

您可以找到完整的文档 here