- 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/
如何对自定义 DelegatingHandler 进行单元测试?我有以下内容,但它提示未设置 innerHandler。 var httpRequestMessage = new HttpReques
我正在尝试记录我的 Web API 项目的 HTTP 响应 header 。 本项目采用VS2012、.NET 4.5和ASP.NET MVC 4开发。 我写了一个 DelegatingHandler
我正在尝试对 DelegateHandler 的实现进行单元测试。我的简化实现: public class FooHandler : DelegatingHandler { prote
我正在尝试对 DelegateHandler 的实现进行单元测试。我的简化实现: public class FooHandler : DelegatingHandler { prote
在 ASP.NET Core 2.1 应用程序中,我使用 HttpClient 发出 REST 请求。我正在使用 DelegatingHandler 来定义一些常见行为。注册我在这里: private
我是依赖注入(inject)的新手,但对 Ninject 和 Ninject.Extensions.Logging 到 [Inject] 我的 ILogger 很满意 无论我需要什么。 但是一些Del
我目前正在使用几个委托(delegate)处理程序(派生自 DelegatingHandler 的类)在发送请求之前处理请求,例如验证签名等。这一切都非常好,因为我不' 必须对所有调用重复签名验证(例
我有代码将命名的 HttpClient 添加到 ServiceCollection 并将 DelegatingHandler 添加到客户端。示例代码: public class MyDelegatin
我正在尝试对 DelegatingHandler 使用依赖注入(inject)包含 2 个接口(interface)和 1 个字符串。 public class MessageHandler : De
DelegatingHandler继承自 HttpMessageHandler .但是,我不明白其中的区别,因为您必须实现相同的方法,SendAsync使两者都起作用。 这两个处理程序有什么区别?我应
我有以下代码,在转发到我的 localhost:1671 时工作正常: protected override async System.Threading.Tasks.Task SendAsync(H
我在类库中有一个自定义的 DelegatingHandler,我需要用 Autofac 注册它。 webapi 宿主解决了它对运行时的依赖,因此宿主没有对该库的引用。 public class Loc
在我的应用程序中,我们从客户端发送大小适中的数据包并接收大小适中的响应,因此我想在向上和返回的过程中实现一些压缩。 在回来的路上它很好,因为我可以依靠 IIS 的动态压缩来为我做这件事,但在回来的路上
在WebAPI自托管应用程序中,DelegatingHandler的SendAsync()方法和ApiController的任何方法是否总是在同一线程上执行? 使用[ThreadStatic]变量将R
我想知道是否可以在 DelegatingHandler 的 SendAsync 方法中访问正在执行(或即将执行)的 Controller ?我似乎不知道如何访问它,我认为这是因为它在 Controll
我正在尝试了解 Web API Http 管道的工作原理! 在我的 Web API 项目中,我使用以下技术来记录/处理异常: ExceptionHandler -> 在全局级别处理异常 Excepti
我正在尝试在 ASP.NET WebAPI 项目中记录整个传入请求和传出响应。虽然我同意 DelegatingHandler,但我的雇主坚持使用 HttpModule。您如何向她解释为什么我们应该使用
我有一个 MVC/Web API 混合项目,我添加了一个简单的 DelegatingHandler 实现来包装 API 响应。这很好用,但处理程序也被调用以请求 MVC Controller 。我的理
我有一个 Web API,它是一个非常薄的基础架构,只包含两个 DelegatingHandler 实现,它们将传入消息分派(dispatch)到业务层中定义的消息处理程序实现。这意味着没有 Cont
我正在阅读文章并检查示例,我发现 Owin 中间件的使用方式与 WebAPI DelegatingHandler 相同:记录传入请求、验证 header 等。 我唯一的理解是 Owin 中间件在管道中
我是一名优秀的程序员,十分优秀!