【发布时间】:2018-07-28 15:12:01
【问题描述】:
因此,ASP.NET Core 应用程序内置了依赖注入。借助 Entity Framework Core,您可以轻松地从控制器操作方法中获取作用域 DbContext 实例。
但这仅限于控制器操作。如果您需要从一个将通过其他方式(如 WebSocket)与浏览器中的视图进行通信的操作启动一个长时间运行的后台任务,那么您突然之间什么都没有了。后台任务不能使用操作的 DbContext,因为它在操作返回时被限定并释放。
一种简单的方法是使用人们所说的服务定位器。这是一些 IServiceProvider 的静态副本,供以后访问和服务解析。 (ASP.NET Core 2.1 可能需要一种不同的方法,因为我已经阅读了in this comment。)但是无论我在哪里看,这都被描述为反模式。它使测试变得更加困难并混淆了依赖关系。好的。
那么对于这种情况,推荐的解决方案是什么?我在不知名的地方。甚至可以从调度程序而不是控制器操作启动的后台任务。附近没有 HTTP 请求。 DI 在这里能为我做什么?有没有不回退到反模式的解决方案?我相信 ASP.NET Core DI 的创建者已经想到了这一点。
有没有办法让服务在那里解决,或者改变我的架构,以便后台任务本身以某种方式从 DI 中出来?
更新: 应评论请求,示例:控制器操作启动某事。这将需要很长时间,例如网络扫描。视图返回类似“亲爱的用户,请稍候,您可以观看此进度条”之类的内容。工作在后台继续,不断将进度和/或结果发布到浏览器。 (浏览器也可能轮询进度。)后台任务需要访问数据库来存储扫描结果。扫描完成后,浏览器可以通过另一个操作来获取它。因此,如果后台任务只使用控制器操作的 DbContext,那么随着操作完成,它将变得不可用。
另一个例子是与请求完全无关的后台服务。定期检查数据库然后执行某些操作的服务。那也需要一个 DbContext 并且没有地方可以尝试窃取它。
【问题讨论】:
-
请添加您所面临问题的具体示例。
-
@Steven 我添加了一些示例。
-
对不起,我应该让自己更清楚;我的意思是代码示例。你能展示一下相关代码吗?
-
我没有准备好显示的代码。而且我不确定您需要查看哪些代码,我认为描述非常适合。想象一个控制器动作和一个使用 DbContext 的任务。就是这样。
标签: asp.net-core dependency-injection asp.net-core-2.1