如何正确使用ICachedServiceProvider注入Typed HttpClient?
使用Typed HttpClient时,尝试通过ICachedServiceProvider直接获取HttpClient实例:
var httpClient = _cachedServiceProvider.GetRequiredService<HttpClient>();
执行时抛出以下异常:
System.InvalidOperationException
An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
但通过构造函数注入Typed HttpClient却能正常运行:
private readonly HttpClient _httpClient; public TestService(HttpClient httpClient) { _httpClient = httpClient; }
ConfigureServices中的配置如下:
private void ConfigureHttpClient(ServiceConfigurationContext context) { var options = context.Services.ExecutePreConfiguredActions<TestOptions>(); context.Services.AddHttpClient<ITestService, TestService>(httpClient => { httpClient.BaseAddress = options.BaseAddress; }); }
请问如何正确通过ICachedServiceProvider获取配置好的Typed HttpClient?
你已经找到的通过IHttpClientFactory获取命名HttpClient的方案是正确的,代码如下:
var httpClientFactory = _cachedServiceProvider.GetRequiredService<IHttpClientFactory>(); var httpClient = httpClientFactory.CreateClient(nameof(ITestService)); // ... var response = await httpClient.PostAsJsonAsync("oauth/token", testRequest);
原因说明
直接调用GetRequiredService<HttpClient>()获取到的是默认的无配置HttpClient实例,并没有绑定你通过AddHttpClient<ITestService, TestService>配置的BaseAddress等参数。
当你使用AddHttpClient<TInterface, TImplementation>注册Typed Client时,ASP.NET Core会做两件事:
- 为
TImplementation类型注入一个已配置好的HttpClient实例 - 同时以
TInterface的类型名称(即nameof(ITestService))作为客户端名称,将配置好的HttpClient注册到IHttpClientFactory中
因此通过IHttpClientFactory.CreateClient(nameof(ITestService)),就能拿到和构造函数注入时完全一致的、已配置BaseAddress的HttpClient实例。
内容的提问来源于stack exchange,提问作者Jakeuj

