My question is a bit related to this: WebApi equivalent for HttpContext.Items with Dependency Injection.
We want to inject a class using HttpContext.Current in WebApi area using Ninject.
My concern is, this could be very dangerous, as in WebApi (everything?) is async.
Please correct me if I am wrong in these points, this is what I investigated so far:
HttpContext.Current gets the current context by Thread (I looked into the implementation directly).
Using HttpContext.Current inside of async Task is not possible, because it can run on another Thread.
WebApi uses IHttpController with method
Task<HttpResponseMessage> ExecuteAsync
=> every request is async => you cannot use HttpContext.Current inside of action method. It could even happen, more Request are executed on the same thread by coicidence.For creating controllers with injected stuff into constructors
IHttpControllerActivator
is used with sync methodIHttpController Create
. This is, where ninject creates Controller with all its dependencies.
If I am correct in all of these 4 points, using of
HttpContext.Current
inside of an action method or any layer below is very dangerous and can have unexpected results. I saw on StackOverflow lot of accepted answers suggesting exactly this. In my opinion this can work for a while, but will fail under load.But when using DI to create a Controller and its dependencies, it is Ok, because this runs on one separated thread. I could get a value from the HttpContext in the constructor and it would be safe?. I wonder if each Controller is created on single thread for every request, as this could cause problem under heavy loads, where all threads from IIS could be consumed.
Just to explain why I want to inject HttpContext stuff:
- one solution would be to get the request in controller action method and pass the needed value all the layers as param until its used somewhere deep in the code.
- our wanted solution: all the layers between are not affected by this, and we can use the injected request somewhere deep in code (e.g. in some
ConfigurationProvider
which is dependent on URL)
Please give me your opinion if I am totally wrong or my suggestions are correct, as this theme seems to be very complicated.
Task.Run(..)
or it could spawn a new thread and in that thread try to get the HttpContext injected.. etc. So what's the difference? – BatteryBackupUnitTask.Run
, you do it by yourself and you know what to expect, this is ok for my. My concern is,as the action-method in webapi is run asynchronously by the framework, it is allways to be considered as async with all its pitfalls. I think, it could even happen, two Requests run on the same thread (this is the purpose of await/async I think) => HttpContext.Current will return wrong value. Actually this issue already hit me once, by realising that log4net LogicalThreadContext.Properties are not working by logging in WebApi, but in MVC they do work. – Lukas K