应该避免使用 IHttpContextAccessor 吗?将用户信息获取到 DI 服务中

问题描述 投票:0回答:1

有很多关于使用 IHttpContextAccessor 在 DI 服务中注入用户信息的信息。不过该界面有警告,建议谨慎使用。

该接口需谨慎使用。它依赖于 AsyncLocal,这可能会对异步调用产生负面性能影响。它还创建了对“环境状态”的依赖,这会使测试变得更加困难。

我认为有人要告诉我的是,注入用户信息是一种代码味道,我应该硬着头皮将其从控制器传递下来?或者我可以在中间件中做一些事情吗?

非常感谢,

詹姆斯

c# asp.net-core dependency-injection httpcontext
1个回答
0
投票

在 .NET(Core)的当前实现中,关于

AsyncLocal
(默认
IHttpContextAccessor
实现背后的机制)的使用,需要考虑一些事项:

  1. 正如文档所述,可能会对性能产生负面影响,尽管我发现这与在基准测试中提高每秒请求数特别相关,而不是对运行任何 I/ O 在请求期间。
  2. 迭代 IAsyncEnumerable(由您或您调用的第三方库)会清除
    AsyncLocal
    的状态,导致
    IHttpContextAccessor
    失去对当前
    HttpContext
    对象的引用。过去三年我一直在跟踪这个问题。我和许多其他人一直在敦促微软解决这个问题,但到目前为止,微软还没有可用的解决方案。甚至没有
    CaptureExecutionContextOnAsyncEnumeration=true
    配置开关,或者如果他们喜欢
    CaptureExecutionContextOnAsyncEnumerationAndYesIUnderstandThePerformanceImpact=true

请注意,虽然文档确实说明了负面性能影响,但实际上没有警告更重要的正确性问题。

不幸的是,文档还指出:

它还会产生对“环境状态”的依赖,这会使测试变得更加困难。

然而,在我看来,这种说法是错误的。虽然

HttpContextAccessor
实现依赖于
AsyncLocal
以及“环境状态”,但类依赖于
IHttpContextAccessor
抽象,并且这个抽象可以被替换(这是 DI 的承诺),这不会限制测试以任何有意义的方式。我不确定这个声明是如何泄漏到文档中的。我怀疑这源自 .NET 的一位首席架构师的意见。早在 2017 年,我就与那位架构师进行了一次关于环境状态和可测试性主题的“讨论”。在那次讨论中,您可以看到我们支持和反对的论点。阅读讨论并表达您自己的意见。 我什至会更进一步说,你的

application

组件无论如何都不应该依赖于 IHttpContextAccessor,因为它将它们耦合到

HttpContext
。相反,它们应该依赖于应用程序定制的抽象。在应用程序的启动路径中,您可以为那些依赖于
HttpContextAccessor
的应用程序定制抽象提供适配器实现。
    

© www.soinside.com 2019 - 2024. All rights reserved.