我的问题与这个有点相关:WebApi中使用HttpContext.Current和Ninject实现依赖注入的等效方法。
我们希望在WebApi区域使用HttpContext.Current和Ninject注入一个类。
我担心这可能是非常危险的,因为在WebApi (所有内容?)都是异步的。
请纠正我,如果我在以下几个方面上有错误,这是我迄今为止调查的结果:
HttpContext.Current通过Thread获取当前上下文(我直接查看了实现)。
在异步任务中使用HttpContext.Current是不可能的,因为它可以在另一个线程上运行。
WebApi使用IHttpController和方法
Task<HttpResponseMessage> ExecuteAsync
=>每个请求都是异步的 =>您不能在操作方法内部使用HttpContext.Current。甚至可能发生多个请求在同一线程上执行的巧合。为了构建具有注入到构造函数中的控制器,使用的是
IHttpControllerActivator
,其中包含同步方法IHttpController Create
,这是ninject创建Controller及其依赖项的位置。
如果我在这四个点上都正确,那么在操作方法或任何位于下层的层中使用
HttpContext.Current
是非常危险且会产生意想不到的结果的。我在StackOverflow上看到很多被接受的答案正是建议这样做的。我认为这可能在一段时间内能够工作,但在负载下将失败。但是,当使用DI创建控制器及其依赖项时,它是可以的,因为它只运行在一个独立的线程上。 我可以在构造函数中获取HttpContext的值,这种方式是安全的吗?我想知道每个控制器是否在每个请求上都是在单个线程上创建的,因为这可能会在负载高时导致问题,其中所有IIS线程都可能被消耗。
只是为了解释我为什么想要注入HttpContext相关内容:
- 一种解决方案是在控制器操作方法中获取请求并将所需值作为参数传递到所有层,直到它在代码的某处深处使用。
- 我们想要的解决方案: 在此之间的所有层都不受影响,并且我们可以在代码的深处使用注入的请求 (例如,在某些依赖于URL的
ConfigurationProvider
中)。
如果我的想法完全错误或者我的建议是正确的,请给我您的意见,因为这个主题似乎非常复杂。
Task.Run(..)
,或者它可以创建一个新线程,在该线程中尝试获取注入的HttpContext..等等。那么有什么区别呢? - BatteryBackupUnitTask.Run
时,你自己知道要做什么并且知道可以期望什么,这对我来说没问题。我的担忧是,由于WebApi中的操作方法是由框架异步运行的,因此它始终应被视为具有所有缺陷的异步操作。我认为,甚至可能发生两个请求在同一个线程上运行(我认为这就是await/async的目的)=> HttpContext.Current将返回错误的值。实际上,这个问题已经让我遇到过一次,我意识到在WebApi中记录日志时,log4net LogicalThreadContext.Properties不起作用,但在MVC中它们确实起作用。 - Lukas K