Phi*_*hil 5 c# asp.net-core asp.net-core-hosted-services asp.net-core-3.0
回到 .net core 2,我创建了一个带有自定义属性的托管服务,例如:
public class MyService : BackgroundService
{
public bool IsRunning {get;set;}
...
Run Code Online (Sandbox Code Playgroud)
我可以在 startup.cs 中设置,如:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHostedService,HostedServices.MyService>();
...
Run Code Online (Sandbox Code Playgroud)
然后我可以在剃刀页面的其他地方引用它,例如:
public class IndexModel : PageModel
{
private readonly IHostedService _mySrv;
public IndexModel(IHostedService mySrv) => _mySrv = mySrv;
[BindProperty]
public bool IsRunning { get; set; }
public void OnGet() => IsRunning = ((HostedServices.MyService)_mySrv).IsRunning;
}
Run Code Online (Sandbox Code Playgroud)
现在我已升级到 .net core 3,我的启动已更改为:
services.AddHostedService<HostedServices.MyService>();
Run Code Online (Sandbox Code Playgroud)
但是我在 IndexModel 中的 DI 引用不再为我提供 MyService,而是为我提供了一个 GenericWebHostService 类型的对象,我无法弄清楚如何从中获取我的自定义 MyService。在 IndexModel 中将“IHostedService”更改为“MyService”也不起作用,我收到“无法解析服务”错误。
如何从依赖注入中取回 MyService 的实例?
Kir*_*kin 12
在 2.2 中,您所做的设置主要是偶然的。每当您针对一项服务注册多个实现时,最后注册的就是“获胜”的那个。例如,采用以下代码:
services.AddSingleton<IHostedService, HostedService1>();
services.AddSingleton<IHostedService, HostedService2>();
// ...
public IndexModel(IHostedServie hostedService) { }
Run Code Online (Sandbox Code Playgroud)
IHostedService注入的实现IndexModel是HostedService2; 最后注册。如果IndexModel要更新为采用IEnumerable<IHostedService>,它将按注册顺序获得两种实现:
public IndexModel(IEnumerable<IHostedService> hostedServices) { }
Run Code Online (Sandbox Code Playgroud)
当我说“偶然”时,我的意思是在您的示例中,只会 HostedServices.MyService注册,因此它也是最后注册的,因此它“获胜”。
在3.0中,使用时一般主机的一种实现IHostedService,GenericWebHostService,把手处理Web请求。这给你一个问题,因为GenericWebHostService注册后 HostedServices.MyService。我希望现在已经清楚了,这就是为什么IHostedService您请求的IndexModel不是您所期望的原因。
在解决方案方面,我建议执行两个注册:
services.AddSingleton<HostedServices.MyService>();
services.AddHostedService(sp => sp.GetRequiredService<HostedServices.MyService>());
Run Code Online (Sandbox Code Playgroud)
然后,更新您IndexModel以要求您的特定实现:
public IndexModel(HostedServices.MyService myService) { }
Run Code Online (Sandbox Code Playgroud)
这使您可以针对特定的IHostedService. 它针对两种不同的服务类型注册了两次,但只创建了一个实例。
| 归档时间: |
|
| 查看次数: |
2464 次 |
| 最近记录: |