[英]Share HttpClient between services
我正在研究一个 Blazor 项目,为了让我更容易理解这个问题,我们可以说我正在使用两种不同的服务来处理身份验证部分。 它们与命名的 httpclient 一起注册在 configureservices 启动方法中。
services.AddHttpClient("XBOWServicesApi", c =>
{
c.BaseAddress = new Uri(XBOWServicesApi);
});
services.AddSingleton<IService1, Service1>();
services.AddSingleton<IService2, Service2>();
服务 1:包含 REST Api 中可用的所有功能。 它使用 http 客户端,该客户端通过实例化的 httpclientfactory 在构造函数中设置。 这需要使用 baseurl 和 Auth-header 进行设置才能工作。
public Service1(IHttpClientFactory clientFactory)
{
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}
服务 2:使用自定义 AuthenticationStateProvider 处理登录/注销功能。 它有自己的httpclient,所以我可以为http客户端设置Auth Header。 构造函数的工作方式与服务 1 相同。
public Service2(IHttpClientFactory clientFactory)
{
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}
这种建立的原因当然是我喜欢共享同一个 http 客户端,所以当它在登录/注销方法中设置时,服务 1 在与 Z8A5DA52ED1205447A8AAZE 通信时将具有正确的身份验证 header。
但是,客户端工厂每次都提供一个新实例,所以这永远不会起作用。
任何想法如何处理这个?
/亨里克
当我阅读Microsoft IHttpClientFactory 文档时:
每次从 IHttpClientFactory 获取 HttpClient object 时,都会返回一个新实例。 但是每个 HttpClient 使用一个由 IHttpClientFactory 汇集和重用的 HttpMessageHandler 来减少资源消耗,只要 HttpMessageHandler 的生命周期没有过期。
这是否回答你的问题?
您可以使用named client
:
services.AddHttpClient("github", c =>
{
c.BaseAddress = new Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});
之后,只需调用带有相应name
参数的CreateClient
方法。
var client = _clientFactory.CreateClient("github");
每次调用CreateClient
时:
您可以在此处的 Microsoft 文档中找到更多详细信息。
您可以使用 HttpMessageHandlers 在瞬态 HttpClients 之间共享作用域服务。
IHttpClient.CreateClient
每次都会返回一个新的实例,但是你可以注册一个HttpMessageHandler
如下所示:
services.AddScoped<HandlerData>();
services.AddTransient<HeaderHandler>();
services.AddHttpClient("XBOWServicesApi", c =>
{
c.BaseAddress = new Uri(XBOWServicesApi);
}).AddHttpMessageHandler<HeaderHandler>();
HeaderHandler Class:
public class HeaderHandler : DelegatingHandler
{
private readonly IHttpContextAccessor httpContextAccessor;
public HeaderHandler(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken )
{
var Data= this.httpContextAccessor.HttpContext.RequestServices.GetRequiredService<HandlerData>();
request.Headers.Add(Data.HeaderName, Data.HeaderValue);
return base.SendAsync(request, cancellationToken);
}
}
处理程序数据 Class:
public class HandlerData
{
public string HeaderName { get; set; }
public string HeaderValue { get; set; }
}
服务代码:
public Service1(IHttpClientFactory clientFactory, HandlerData data)
{
data.HeaderName = "Header1";
data.HeaderValue = "Value";
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}
public Service2(IHttpClientFactory clientFactory)
{
//This will contain the same headers as Service1 as HandlerData is Scoped Service
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}
或者,如果您需要创建与您请求相同的 DI scope 的处理程序,您也可以使用新的IHttpMessageHandlerFactory
:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.