Use scoped services within a BackgroundService | 您所在的位置:网站首页 › addscope › Use scoped services within a BackgroundService |
Use scoped services within a BackgroundService
Article12/13/2023
When you register implementations of IHostedService using any of the AddHostedService extension methods - the service is registered as a singleton. There may be scenarios where you'd like to rely on a scoped service. For more information, see Dependency injection in .NET: Service lifetimes. In this tutorial, you learn how to: Resolve scoped dependencies in a singleton BackgroundService. Delegate work to a scoped service. Implement an override of BackgroundService.StopAsync(CancellationToken).Tip All of the "Workers in .NET" example source code is available in the Samples Browser for download. For more information, see Browse code samples: Workers in .NET. Prerequisites The .NET 8.0 SDK or later A .NET integrated development environment (IDE) Feel free to use Visual Studio Create a new projectTo create a new Worker Service project with Visual Studio, you'd select File > New > Project.... From the Create a new project dialog search for "Worker Service", and select Worker Service template. If you'd rather use the .NET CLI, open your favorite terminal in a working directory. Run the dotnet new command, and replace the with your desired project name. dotnet new worker --nameFor more information on the .NET CLI new worker service project command, see dotnet new worker. Tip If you're using Visual Studio Code, you can run .NET CLI commands from the integrated terminal. For more information, see Visual Studio Code: Integrated Terminal. Create scoped servicesTo use scoped services within a BackgroundService, create a scope. No scope is created for a hosted service by default. The scoped background service contains the background task's logic. namespace App.ScopedService; public interface IScopedProcessingService { Task DoWorkAsync(CancellationToken stoppingToken); }The preceding interface defines a single DoWorkAsync method. To define the default implementation: The service is asynchronous. The DoWorkAsync method returns a Task. For demonstration purposes, a delay of ten seconds is awaited in the DoWorkAsync method. An ILogger is injected into the service.: namespace App.ScopedService; public sealed class DefaultScopedProcessingService( ILogger logger) : IScopedProcessingService { private int _executionCount; public async Task DoWorkAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { ++ _executionCount; logger.LogInformation( "{ServiceName} working, execution count: {Count}", nameof(DefaultScopedProcessingService), _executionCount); await Task.Delay(10_000, stoppingToken); } } }The hosted service creates a scope to resolve the scoped background service to call its DoWorkAsync method. DoWorkAsync returns a Task, which is awaited in ExecuteAsync: Rewrite the Worker classReplace the existing Worker class with the following C# code, and rename the file to ScopedBackgroundService.cs: namespace App.ScopedService; public sealed class ScopedBackgroundService( IServiceScopeFactory serviceScopeFactory, ILogger logger) : BackgroundService { private const string ClassName = nameof(ScopedBackgroundService); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { logger.LogInformation( "{Name} is running.", ClassName); await DoWorkAsync(stoppingToken); } private async Task DoWorkAsync(CancellationToken stoppingToken) { logger.LogInformation( "{Name} is working.", ClassName); using (IServiceScope scope = serviceScopeFactory.CreateScope()) { IScopedProcessingService scopedProcessingService = scope.ServiceProvider.GetRequiredService(); await scopedProcessingService.DoWorkAsync(stoppingToken); } } public override async Task StopAsync(CancellationToken stoppingToken) { logger.LogInformation( "{Name} is stopping.", ClassName); await base.StopAsync(stoppingToken); } }In the preceding code, an explicit scope is created and the IScopedProcessingService implementation is resolved from the dependency injection service scope factory. The resolved service instance is scoped, and its DoWorkAsync method is awaited. Replace the template Program.cs file contents with the following C# code: using App.ScopedService; HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); builder.Services.AddHostedService(); builder.Services.AddScoped(); IHost host = builder.Build(); host.Run();The services are registered in (Program.cs). The hosted service is registered with the AddHostedService extension method. For more information on registering services, see Dependency injection in .NET. Verify service functionalityTo run the application from Visual Studio, select F5 or select the Debug > Start Debugging menu option. If you're using the .NET CLI, run the dotnet run command from the working directory: dotnet runFor more information on the .NET CLI run command, see dotnet run. Let the application run for a bit to generate several execution count increments. You will see output similar to the following: info: App.ScopedService.ScopedBackgroundService[0] ScopedBackgroundService is running. info: App.ScopedService.ScopedBackgroundService[0] ScopedBackgroundService is working. info: App.ScopedService.DefaultScopedProcessingService[0] DefaultScopedProcessingService working, execution count: 1 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: .\scoped-service info: App.ScopedService.DefaultScopedProcessingService[0] DefaultScopedProcessingService working, execution count: 2 info: App.ScopedService.DefaultScopedProcessingService[0] DefaultScopedProcessingService working, execution count: 3 info: App.ScopedService.DefaultScopedProcessingService[0] DefaultScopedProcessingService working, execution count: 4 info: Microsoft.Hosting.Lifetime[0] Application is shutting down... info: App.ScopedService.ScopedBackgroundService[0] ScopedBackgroundService is stopping.If running the application from within Visual Studio, select Debug > Stop Debugging.... Alternatively, select Ctrl + C from the console window to signal cancellation. See also Worker Services in .NET Create a Queue Service Create a Windows Service using BackgroundService Implement the IHostedService interface |
CopyRight 2018-2019 实验室设备网 版权所有 |