代码之家  ›  专栏  ›  技术社区  ›  ygoe

从后台任务访问dbContext服务

  •  5
  • ygoe  · 技术社区  · 6 年前

    因此,ASP.NET核心应用程序内置了依赖注入。使用EntityFramework核心,您可以很容易地从控制器操作方法中获取一个作用域dbContext实例。

    但这些都局限于控制者的行为。如果您需要从一个操作开始一个长期运行的后台任务,该操作将通过其他方式(如WebSocket)与浏览器中的视图进行通信,那么您突然就什么都没有了。后台任务无法使用该操作的dbContext,因为在该操作返回时已对其进行了范围界定和释放。

    一个简单的方法是使用人们所称的服务定位器。这是某些ISeviceProvider的静态副本,以供以后访问和服务解析。(ASP.NET核心2.1可能需要不同的方法,正如我所读到的 in this comment 但无论我在哪里看,这都被描述为反模式。它使测试更加困难,并使依赖项变得模糊。好吧。

    那么,对于这个场景,推荐的解决方案是什么?我不知在哪里。甚至可以从调度程序而不是控制器操作启动的后台任务。附近没有HTTP请求。我能在这里为我做什么?有没有一个解决方案没有回到反模式?我确信ASP.NET核心DI的创建者已经考虑过这个问题。

    有没有一种方法可以在那里解决服务问题,或者改变我的体系结构,使后台任务以某种方式从DI中出来?

    更新: 由注释请求,例如:控制器操作启动某些内容。这需要很长时间,就像网络扫描一样。视图返回时带有“亲爱的用户,请稍候,您可以观看此进度条。”工作将在后台继续,并将进度和/或结果持续发布到浏览器。(浏览器可能也会轮询进度。)后台任务需要访问数据库来存储扫描结果。扫描完成后,浏览器可以通过另一个操作获取它。因此,如果后台任务只使用controller操作的dbContext,那么在操作完成后,它将变得不可用。

    另一个例子是与请求完全无关的后台服务。一种定期检查数据库然后执行某些操作的服务。这还需要一个dbContext,甚至没有地方可以尝试窃取它。

    1 回复  |  直到 6 年前
        1
  •  5
  •   alsami    6 年前

    IServiceScopeFactory

    using (var scope = _serviceScopeFactory.CreateScope())
    {
       var context = scope.ServiceProvider.GetRequiredService<DbContext>();
       // now do your work
    }
    

    IHostedService

    link