您如何依赖将服务注入IHostedService(计划作业)?

时间:2020-10-12 00:06:48

标签: c# asp.net-core dependency-injection service

意图:我想构建一个cronjob,该缓存将使用当前数据覆盖缓存中的内存。它应该是单独的服务。

我有一个名为TimedHostedService的IHostedService和一个名为ExampleService的自定义服务。应将示例注入TimedHostedService中,以便它可以从ExampleService中调用方法。 ExampleService应该是覆盖内存的唯一服务

问题:当程序尝试将ExampleService注入TimedHostedService时崩溃。出现以下错误消息。

AggregateException:无法构造某些服务(验证服务描述符'ServiceType:Microsoft.Extensions.Hosting.IHostedService寿命:Singleton ImplementationType:Example_Project.Backend.Job.TimedHostedService'时出错:无法使用作用域服务'Example_Project单例Microsoft.Extensions.Hosting.IHostedService中的.Services.IExampleService”。) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors,ServiceProviderOptions选项)

InvalidOperationException:验证服务时出错 描述符'ServiceType:Microsoft.Extensions.Hosting.IHostedService 生命周期:单例实施类型: Example_Project.Backend.Job.TimedHostedService':无法使用 范围有限的服务“ Example_Project.Services.IExampleService”,来自 单例“ Microsoft.Extensions.Hosting.IHostedService”。

代码

StartUp.cs

public void ConfigureServices(IServiceCollection services)
    {
        /* Add MemoryCache */
        services.AddMemoryCache();

        /* Add CronJob / Scheduled Job */
        services.AddHostedService<TimedHostedService>();

        /* Add Dependency Injection of ExampleService */
        services.AddScoped<IExampleService, ExampleService>();
}

ExampleService.cs

public interface IExampleService
{
    void SetExample();
    IInventoryArticle[] GetExamples();
}

public class ExampleService : IExampleService
{
    public Examples[] GetExamples()
    { return null; }

    public void SetExample()
    { }

}

TimedHostedService.cs

public class TimedHostedService : IHostedService, IDisposable
    {
        private readonly ILogger<TimedHostedService> _logger;
        private Timer _timer;
        private readonly IInventoryService _inventoryService;

        public TimedHostedService(
            ILogger<TimedHostedService> logger,
            IInventoryService inventoryService)
        {
            _logger = logger;
            _inventoryService = inventoryService; /// Problem Child
        }
}

1 个答案:

答案 0 :(得分:1)

如果您想使用范围服务,则需要自己创建一个范围;

        private readonly IServiceProvider serviceProvider;

        public TimedHostedService(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
            //...
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            using (var scope = serviceProvider.CreateScope())
            {
                var ... = scope.ServiceProvider.GetService<...>();
                //...
            }
        }