So ASP.NET Core applications have Dependency Injection built right in. And with Entity Framework Core, you can easily get a scoped DbContext instance from a controller action method.
But this is all limited to controller actions. If you need to start a long-running background task from an action that will communicate with the view in the browser by other means like WebSocket, then you suddenly have nothing at all. The background task can't use the action's DbContext because that was scoped and disposed of when the action returns.
An easy way would be to use what people call a Service Locator. This is a static copy of some IServiceProvider for later access and service resolution. (ASP.NET Core 2.1 might need a different approach as I've read in this comment.) But whereever I look, this is described as anti-pattern. It makes testing harder and obfuscates dependencies. Alright.
So what's the recommended solution for this scenario? I'm somewhere in the middle of nowhere. A background task that might even be started from a scheduler instead of a controller action. No HTTP request anywhere near. What can DI do for me here? Is there a solution without falling back to anti-patterns? I'm sure the creators of ASP.NET Core DI have thought of this.
Is there either a way to get the services resolved there, or change my architecture so that the background task itself comes out of DI somehow?
Update: Requested by a comment, an example: A controller action starts something. This will take a long time, like a network scan. The view returns with something like "Dear user, please wait while you can watch this progress bar." Work continues in the background, continually posting the progress and/or results to the browser. (The browser might also poll progress instead.) The background task needs access to the database to store the scan results. When the scan is finished, the browser can fetch it through another action. So if the background task would just use the controller action's DbContext, that would become unusable as the action has completed.
Another example is a background service that isn't related to a request at all. A service that regularly checks the database and then does something. That also needs a DbContext and has nowhere to even try to steal it.