简体   繁体   English

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

[英]How to reference a hosted service in .Net Core 3?

Back in .net core 2, I had created a hosted service with a custom property like:回到 .net 核心 2 中,我创建了一个具有自定义属性的托管服务,例如:

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

That I could setup in startup.cs like:我可以在 startup.cs 中设置,例如:

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

And then I could reference it elsewhere in a razor page like:然后我可以在 razor 页面的其他地方引用它,例如:

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

Now that I've upgraded to .net core 3, my startup has changed to:现在我已经升级到 .net 核心 3,我的启动已更改为:

services.AddHostedService<HostedServices.MyService>();

But my DI reference in IndexModel doesn't get me my MyService anymore, it gives me an object of type GenericWebHostService instead, that I can't figure out how to get my custom MyService from.但是我在 IndexModel 中的 DI 引用不再让我获得 MyService,而是给我一个 GenericWebHostService 类型的 object,我不知道如何从中获取我的自定义 MyService。 Changing 'IHostedService' to 'MyService' in IndexModel doesn't work either, i get a 'Unable to resolve service' error.在 IndexModel 中将“IHostedService”更改为“MyService”也不起作用,我收到“无法解析服务”错误。

How do I get an instance of MyService back from dependency injection?如何从依赖注入中获取 MyService 的实例?

In 2.2, the setup you had worked mostly by chance.在 2.2 中,您使用的设置主要是偶然的。 Whenever you register multiple implementations against a service, the last-registered is the one that "wins".每当您针对服务注册多个实现时,最后注册的是“获胜”的那个。 For example, take the following code:例如,采用以下代码:

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

// ...

public IndexModel(IHostedServie hostedService) { }

The implementation of IHostedService that gets injected into IndexModel is HostedService2 ;注入IHostedServiceIndexModel的实现是HostedService2 the last registered.最后注册。 If IndexModel were to be updated to take an IEnumerable<IHostedService> , it would get both implementations, in order of registration:如果要更新IndexModel以采用IEnumerable<IHostedService> ,它将获得两种实现,按注册顺序:

public IndexModel(IEnumerable<IHostedService> hostedServices) { }

When I said "by chance", I meant that in your example, only HostedServices.MyService gets registered, so it's also the last-registered and therefore it "wins".当我说“偶然”时,我的意思是在您的示例中,只有HostedServices.MyService被注册,所以它也是最后注册的,因此它“获胜”。

In 3.0, when using the Generic Host , an implementation of IHostedService , GenericWebHostService , handles processing web requests.在 3.0 中,使用Generic Host时, IHostedService的实现GenericWebHostService处理处理 web 请求。 This gives you a problem, because the GenericWebHostService is registered after HostedServices.MyService .这会给您带来问题,因为GenericWebHostServiceHostedServices.MyService之后注册的。 I hope it's clear by now that this is the reason why the IHostedService you request in IndexModel is not what you expected.我希望现在很清楚,这就是您在IndexModel IHostedService您所期望的原因。

In terms of a solution, I suggest performing two registrations:在解决方案方面,我建议执行两个注册:

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

Then, update your IndexModel to require your specific implementation:然后,更新您的IndexModel以要求您的特定实现:

public IndexModel(HostedServices.MyService myService) { }

This allows you to target your specific implementation of IHostedService .这使您可以针对IHostedService的特定实现。 It's registered twice, against two different service types, but only one instance gets created.它针对两种不同的服务类型注册了两次,但只创建了一个实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM