Asp.net core 无法将BackgroundService注入PageModel

Asp.net core 无法将BackgroundService注入PageModel,asp.net-core,Asp.net Core,我正在尝试使用BackgroundService,它是一个asp.NETCore2.2项目,使用RazorPage项目模板,而不是MVC。这个小示例应用程序花了我大约1分钟的时间来编写,所以它非常简单。看着调试器,我知道后台服务正在启动,并且运行得很好。但是,当我尝试导航到需要此服务作为依赖项的页面路径“Banana”时,我会遇到InvalidOperationException:在尝试激活“WebApplication23.Pages.BananaModel”时,无法解析类型为“WebAppl

我正在尝试使用BackgroundService,它是一个asp.NETCore2.2项目,使用RazorPage项目模板,而不是MVC。这个小示例应用程序花了我大约1分钟的时间来编写,所以它非常简单。看着调试器,我知道后台服务正在启动,并且运行得很好。但是,当我尝试导航到需要此服务作为依赖项的页面路径“Banana”时,我会遇到InvalidOperationException:在尝试激活“WebApplication23.Pages.BananaModel”时,无法解析类型为“WebApplication23.DumbService”的服务。为什么我不能从我的页面模型访问此服务?代码在

我有以下服务:

using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;

namespace WebApplication23
{
    public class DumbService : BackgroundService
    {
        public DumbService()
        {

        }

        public void QueueWork()
        {

        }

        protected async override Task ExecuteAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested) {
                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }
    }
}
这是我注册的地方:

services.AddHostedService<DumbService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

注册后台服务实际上并不会将其添加到服务集合中,主要是因为不需要这样做。后台服务的全部意义在于,你的应用并不需要真正了解它。不清楚您为什么认为需要注入此服务,但几乎可以肯定的是,将Razor页面中需要的任何逻辑分解到一个单独的类中,该服务和Razor页面都可以使用,这样会更好地为您服务

更新


看。您会注意到,实际托管的服务被注入了任务队列。然后,您的应用程序还将只注入任务队列本身来安排任务。

后台服务是在后台自行运行的服务,而不是要注入控制器或页面模型的服务。这并不是一项单身服务。如果你想从你的页面模型中停止/启动/管理它,你必须注册它,就像Chris Pratt解释的那样,不管真正的问题是什么,它都可以在不向页面模型中注入后台服务的情况下得到解决。例如,如果该服务对已发布的消息执行一些繁重的操作,那么您只需要一个允许向其发布的接口,例如IWriter,而不需要访问该服务本身。是的,我的页面模型只需要访问后台服务上的一个方法,比如“QueueWork…”。我将看看是否可以将其注入到我的页面模型中,而不是整个后台服务中。但是,新的紧密关注的服务需要将后台服务作为依赖项注入其中。我会看看我是否能让它工作。你可以用服务实现的方法创建一个接口。在ConfigureServices中,您可以调用重载来访问现成的实例并传递后台服务。后台服务公开了一个类似“QueueWork…”的方法,我需要从页面模型中调用该方法。我将尝试将其重构为一个新服务,但该服务需要将后台服务作为依赖项注入其构造函数中。所以要么后台服务被注入到页面模型中,要么它被注入到另一个被注入到页面模型中的服务中。对我来说,这似乎有点自上而下。我创建了一个名为IWorkQueue的服务,将其设置为单例,并将其注入到我的后台服务和页面模型中。IHostedService实现不是应用程序域的一部分。注入一个本身独立于将被注入的应用程序的服务是没有意义的。这将产生各种各样的问题,比如服务必须如何启动/停止,以及在应用程序层中创建一个故意松散的硬依赖关系。外部化队列允许双方独立运行。你的应用程序只需安排任务,而不必担心任务的处理方式或时间。该服务只运行任务,不必担心任务来自何处。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace WebApplication23.Pages
{
    public class BananaModel : PageModel
    {
        private readonly DumbService _service;

        public BananaModel(DumbService service)
        {
            _service = service;
        }

        public void OnGet()
        {

        }
    }
}