如何结合AddHttpMessageHandler使用ITypedHttpClientFactory?
我为类型化客户端TypedClient注册了一个AuthorizationHandler,代码如下:
var clientFactory = services.BuildServiceProvider().GetRequiredService<IHttpClientFactory>(); services.AddHttpClient<TypedClient>() .AddHttpMessageHandler(() => { var authorization = new BearerAuthorization(clientFactory, clientId, clientSecret, authHost, token); return new AuthorizationHandler(authorization); });
当直接从依赖注入容器获取TypedClient时,一切正常,AuthorizationHandler会在请求前被调用:
_typedClient = serviceProvider.GetRequiredService<TypedClient>(); await _typedClient.SendRequest(); // 正常工作
但当尝试通过ITypedHttpClientFactory工厂获取该客户端时,处理器不再被调用,导致授权错误:
_httpClientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>(); _typedClientFactory = serviceProvider.GetRequiredService<ITypedHttpClientFactory<TypedClient>>(); using var client = _httpClientFactory.CreateClient(); using var typedClient = _typedClientFactory.CreateClient(client); await typedClient.SendRequest(); // 授权失败
请问如何从工厂获取能在请求前触发已添加处理器的类型化客户端?
解决方案
问题出在你直接调用IHttpClientFactory.CreateClient()时,创建的是默认HttpClient实例,这个实例并没有绑定你为TypedClient配置的AuthorizationHandler。用ITypedHttpClientFactory.CreateClient(client)包装它时,只会把裸的HttpClient注入到TypedClient中,自然不会触发注册的处理器。
正确做法1:使用对应TypedClient的命名HttpClient
AddHttpClient<TypedClient>会自动生成一个以类型全名为标识的命名客户端,创建这个命名客户端再包装成类型化客户端即可:
_httpClientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>(); _typedClientFactory = serviceProvider.GetRequiredService<ITypedHttpClientFactory<TypedClient>>(); // 创建对应TypedClient的命名HttpClient using var client = _httpClientFactory.CreateClient(typeof(TypedClient).FullName); using var typedClient = _typedClientFactory.CreateClient(client); await typedClient.SendRequest(); // 正常工作
正确做法2:直接通过IHttpClientFactory获取类型化客户端
这是更简洁的方式,本质和依赖注入直接获取一致:
_httpClientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>(); // 直接获取带配置的TypedClient var typedClient = _httpClientFactory.CreateClient<TypedClient>(); await typedClient.SendRequest(); // 正常工作
额外优化:修复注册时的潜在问题
你提前调用services.BuildServiceProvider()获取IHttpClientFactory会创建独立的服务提供者实例,可能导致依赖注入不一致。建议改为通过工厂方法参数注入获取:
services.AddHttpClient<TypedClient>() .AddHttpMessageHandler(sp => { var clientFactory = sp.GetRequiredService<IHttpClientFactory>(); var authorization = new BearerAuthorization(clientFactory, clientId, clientSecret, authHost, token); return new AuthorizationHandler(authorization); });
内容的提问来源于stack exchange,提问作者Alseratia
相关产品推荐
相关产品推荐

