如何在.Net Core 3中引用托管服务?

问题描述 投票:1回答:1

回到.net core 2,我创建了一个具有自定义属性的托管服务,例如:

 public class MyService : BackgroundService 
{
public bool IsRunning {get;set;}
...

我可以在startup.cs中进行设置,例如:

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHostedService,HostedServices.MyService>();
...

然后我可以在剃刀页面的其他地方引用它,例如:

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;
}

现在我已经升级到.net core 3,我的启动已更改为:

services.AddHostedService<HostedServices.MyService>();

但是我在IndexModel中的DI参考不再给我MyService了,它给了我一个GenericWebHostService类型的对象,我不知道如何从中获取我的自定义MyService。在IndexModel中将'IHostedService'更改为'MyService'也不起作用,我收到“无法解析服务”错误。

如何从依赖项注入取回MyService的实例?

c# asp.net-core asp.net-core-3.0 asp.net-core-hosted-services
1个回答
0
投票

在2.2中,您主要是偶然地进行设置。每当您针对一个服务注册多个实现时,最后注册的将是“获胜”的实现。例如,使用以下代码:

services.AddSingleton<IHostedService, HostedService1>();
services.AddSingleton<IHostedService, HostedService2>();

// ...

public IndexModel(IHostedServie hostedService) { }

[注入到IHostedService中的IndexModel的实现是HostedService2;最后一次注册。如果将IndexModel更新为IEnumerable<IHostedService>,它将按注册顺序获得both实现:

public IndexModel(IEnumerable<IHostedService> hostedServices) { }

[当我说“偶然”时,我是说在您的示例中,[[only HostedServices.MyService被注册,因此它也是最后注册的,因此它“获胜”。]]在3.0中,当使用Generic Host时,IHostedServiceGenericWebHostService的实现处理Web请求的处理。这给您带来了问题,因为GenericWebHostService被注册为[[after

HostedServices.MyService。我希望现在很清楚,这就是您在IHostedService中请求的IndexModel超出预期的原因。

就解决方案而言,我建议执行两次注册:

services.AddSingleton<HostedServices.MyService>(); services.AddHostedService(sp => sp.GetRequiredService<HostedServices.MyService>());

然后,更新您的IndexModel以要求您的特定实现:

public IndexModel(HostedServices.MyService myService) { }

这使您可以定位IHostedService的特定实现。它针对两种不同的服务类型进行了两次注册,但是只创建了一个实例。

© www.soinside.com 2019 - 2024. All rights reserved.