【问题标题】:.net core dependency injection to hosted service [duplicate].net核心依赖注入到托管服务[重复]
【发布时间】:2019-01-31 21:34:43
【问题描述】:

我的 .net 核心应用需要在指定的时间间隔内爬取数据。我选择实现IHostedService 以与API 并行运行它。托管服务需要注入一些服务。我在startup.cs 中注册了它们,但出现错误:

System.InvalidOperationException: '不能使用单例'Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor'中的范围服务'IXService'。'

我的 startup.cs:

services.AddScoped<IXService, XService>();
services.AddHostedService<MyHostedService>();

我在使用 DbContext 时遇到了类似的问题,我使用 https://stackoverflow.com/a/48368934/8475133 解决了它,但这次我需要通过更深层次的依赖注入,并且在每个层中处理 IServiceScopeFactory 似乎不是一个优雅的解决方案。

【问题讨论】:

  • 我不明白。如果您可以为DbContext 解决同样的问题,为什么您不能为MyHostedService 需要的其余服务解决它?
  • "...似乎不是一个优雅的解决方案",假设我有很多服务要深入注入,每个服务都在构造函数中消耗一些其他服务,这个解决方案会导致额外的代码行使用 usings ,而标准的依赖注入只是注册服务的几行代码,然后将它们包含在构造函数的参数中,这就更清楚了。
  • 但您接受了与您在问题上发布的链接重复的答案?

标签: c# asp.net-core dependency-injection asp.net-core-hosted-services


【解决方案1】:

您不允许这样做的原因是因为 MyHostedService 有一个单例生命周期,它比作用域的生命周期更长。这里的基本假设是注册为作用域的服务不应该无限期地保持活动状态,如果单例服务保持对作用域服务的引用,这很容易发生。

我认为您正在寻找的解决方案是将 IServiceProvider 注入 MyHostedService,在需要时使用它来创建新的范围和新的 XService 实例。

即替换

_xService.Foo();

与

using(var scope = _serviceProvider.CreateScope()) {
    var xService = scope.ServiceProvider.GetService<IXService>();
    xService.Foo();
}

当然,另一种方法是简单地将 XService 注册为单例,只需将 AddScoped 调用替换为 AddSingleton,但我不建议这样做。

编辑:我必须承认在发布我的回复之前没有阅读您的链接。但是,我仍然认为这是最优雅的解决方案。

【讨论】:

  • 这并不完全正确。 AddHostedService 将它们添加为瞬态,但它们仅由 HostedServiceExecutor docs.microsoft.com/en-us/dotnet/api/… 创建一次。
  • 谢谢指正,我看错了错误信息。它清楚地表明 HostedServiceExecutor。
  • 只是为了更新。 2018 年 11 月,代码被更改为注册为单例,这非常重要。它允许其他请求检索与单例相同的托管服务。请参阅 AspNetCore/#4147 使 AddHostedService 在 github 上注册单例 github.com/dotnet/extensions/commit/…
猜你喜欢
  • 2020-01-17
  • 2018-12-14
  • 2019-02-16
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多