8

我的 .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 似乎不是一个优雅的解决方案。

4

1 回答 1

14

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

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

也就是说,更换

_xService.Foo();

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

当然,另一种方法是简单地将 XService 注册为单例,只需用 AddSingleton 替换对 AddScoped 的调用,但我不推荐它。

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

于 2018-08-25T20:27:29.943 回答