- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 ASP.NET Core 2.1 应用程序中,我使用 HttpClient
发出 REST 请求。我正在使用 DelegatingHandler 来定义一些常见行为。注册我在这里:
private static void AddRestServiceDataClient<TTypedHttpClient, TTypedHttpClientImpl>(this IServiceCollection services)
where TTypedHttpClient : class
where TTypedHttpClientImpl : RestServiceDataClient, TTypedHttpClient
{
var httpClientBuilder = services
.AddHttpClient<TTypedHttpClient, TTypedHttpClientImpl>()
.AddHttpMessageHandler<CachingHttpDelegatingHandler>()
.AddHttpMessageHandler<ExceptionHttpDelegatingHandler>()
.AddHttpMessageHandler<LoggingHttpDelegatingHandler>();
}
...
// EDIT: You should always register DelegatingHandlers as TRANSIENT (read answer for more).
services.AddScoped<ExceptionHttpDelegatingHandler>();
services.AddScoped<CachingHttpDelegatingHandler>();
services.AddScoped<LoggingHttpDelegatingHandler>();
我将DelegatingHandler
注册为Scoped,但在两个不同的范围(请求)中我得到相同的DelegatingHandler
。我的意思是 DelegationgHandler 的构造函数仅被调用一次,并且在更多请求中使用相同的实例(如单例)。其他一切都符合预期 - 其他服务、TypedHttpClients 和 HttpClient 的生命周期都正常。
我通过构造函数中的断点测试了所有内容,并且在每个实例中测试了 Guid,以便我可以区分实例。
当我将 DelegatingHandler 注册为 Transient 时,没有什么区别。
TL;DR DelegatingHandler
像单例一样解析,即使它们注册为作用域。这导致我的服务生活方式发生困惑。
最佳答案
经过一番调查,我发现尽管 DelegatingHandler
是通过依赖注入(inject)解决的,但 DelegatingHandler
的生命周期有点出乎意料,需要更深入的了解 .NET Core 2.1 中的 HttpClientFactory
。
HttpClientFactory
每次都会创建新的 HttpClient
,但在多个 HttpClient
之间共享 HttpMessageHandler
。有关此的更多信息,您可以在 Steve Gordon's article 中找到.
因为 DelegatingHandler
的实际实例保存在 HttpMessageHandler
内部(在 InnerHandler
属性中递归),并且 HttpMessageHandler
是共享,那么 DelegatingHandler
将以相同的方式共享,并且与共享的 HttpMessageHandler
具有相同的生命周期。
服务提供者在这里仅用于在HttpClientFactory
“决定”时创建新的DelegatingHandler
- 因此每个DelegatingHandler
必须注册为 transient !否则你会得到不确定的行为。 HttpClientFactory
将尝试重用已使用的 DelegatingHandler
。
解决方法
如果需要在DelegatingHandler
中解析依赖关系,可以在构造函数中解析IHttpContextAccessor
,然后在httpContextAccessor中通过
.ServiceProvider
解析依赖关系。 HttpContext.RequestServices
这种方法并不完全是“架构上干净的”,但它是我发现的唯一解决方法。
示例:
internal class MyDelegatingHandler : DelegatingHandler
{
private readonly IHttpContextAccessor httpContextAccessor;
protected MyDelegatingHandler(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var serviceProvider = this.httpContextAccessor.HttpContext.RequestServices;
var myService = serviceProvider.GetRequiredService<IMyService>();
...
}
}
关于.net - HttpClient DelegatingHandler 意外的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53223411/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!