[英]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
;注入IHostedService
的IndexModel
的实现是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
.这会给您带来问题,因为GenericWebHostService
是在HostedServices.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.