IHttpClientFactory 并更改基础 HttpClient.BaseAddress

Xap*_*ann 4 c# wpf dependency-injection dotnet-httpclient

IHttpClientFactory 和更改 HttpClient.BaseAddress 的最佳实践是什么?

在创建我的依赖注入时,我是这样做的:

services.AddHttpClient("MyApp", c =>
    {
        c.BaseAddress = new Uri("https://myurl/");
        c.DefaultRequestHeaders.Add("Accept", "application/json");
    }).ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler()
    { AutomaticDecompression = DecompressionMethods.GZip });
Run Code Online (Sandbox Code Playgroud)

然后当我需要一个 HttpClient 这样做时:

var client = clientFactory.CreateClient("MyApp");
Run Code Online (Sandbox Code Playgroud)

这很有效,但有时在运行时需要更改 BaseAddress。在运行期间,我无法在注入后更改 BaseAddress。现在我可以完全忽略 BaseAddress 并在 API 调用中发送整个地址,但是,我不知道这是否是正确的做法。像这样的东西:

await using var stream = await client.GetStreamAsync($"{addresss}/{api}");
using var streamReader = new StreamReader(stream);
using var textReader = new JsonTextReader(streamReader);
var serializer = new JsonSerializer();
data = serializer.Deserialize<List<T>>(textReader);
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 6

有时,在运行时 BaseAddress 需要更改。在运行期间,我无法在注入后更改 BaseAddress。

BaseAddress可以更改直到发送第一个请求。那时,它被锁定并且无法再次更改。该HttpClient工厂模式假定每个注入客户端仅具有一个BaseAddress(其可以是未固化的)。

现在我可以完全忽略 BaseAddress 并在 API 调用中发送整个地址,但是,我不知道这是否是正确的做法。

您的选择是:

  1. 定义多个客户端,每个客户端一个BaseAddress。如果您有几个知名主机,这是正常方法。
  2. 定义单个客户端,不要使用BaseAddress, 在每次调用中传递整个 url。这是完全允许的。
  3. 定义您自己的工厂类型,用于IHttpClientFactory传递HttpClient实例,其中每个实例都可以指定自己的BaseAddress. 如果你有一些代码,我只会用这种比较复杂的方法需要一个BaseAddress(例如,重新安装),但与动态主机使用需要。