Scoped services binnen een BackgroundService
Wanneer u implementaties registreert van IHostedService het gebruik van een van de AddHostedService extensiemethoden, wordt de service geregistreerd als een singleton. Er kunnen scenario's zijn waarin u afhankelijk wilt zijn van een scoped service. Zie Afhankelijkheidsinjectie in .NET: Levensduur van de service voor meer informatie.
In deze zelfstudie leert u het volgende:
- Bereikafhankelijkheden in een singleton BackgroundServiceoplossen.
- Werk delegeren aan een bereikservice.
- Implementeer een
override
van BackgroundService.StopAsync(CancellationToken).
Tip
Alle voorbeeldbroncode 'Workers in .NET' is beschikbaar in de voorbeeldenbrowser om te downloaden. Zie Codevoorbeelden bekijken: Workers in .NET voor meer informatie.
Vereisten
- De .NET 8.0 SDK of hoger
- Een .NET Integrated Development Environment (IDE)
Een nieuw project maken
Als u een nieuw Worker Service-project wilt maken met Visual Studio, selecteert u Bestand>nieuw>project.... Zoek in het dialoogvenster Een nieuw project maken naar 'Worker Service' en selecteer de sjabloon Worker Service. Als u liever de .NET CLI gebruikt, opent u uw favoriete terminal in een werkmap. Voer de dotnet new
opdracht uit en vervang de door de <Project.Name>
gewenste projectnaam.
dotnet new worker --name <Project.Name>
Zie dotnet new worker voor meer informatie over de opdracht .NET CLI new worker service project.
Tip
Als u Visual Studio Code gebruikt, kunt u .NET CLI-opdrachten uitvoeren vanuit de geïntegreerde terminal. Zie Visual Studio Code: Integrated Terminal voor meer informatie.
Bereikservices maken
Als u scoped services binnen een BackgroundService
bereik wilt gebruiken, maakt u een bereik. Er wordt standaard geen bereik gemaakt voor een gehoste service. De scoped background-service bevat de logica van de achtergrondtaak.
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
De voorgaande interface definieert één DoWorkAsync
methode. De standaard implementatie definiëren:
- De service is asynchroon. De
DoWorkAsync
methode retourneert eenTask
. Voor demonstratiedoeleinden wordt een vertraging van tien seconden in deDoWorkAsync
methode verwacht. - Er ILogger wordt een in de service geïnjecteerd.:
namespace App.ScopedService;
public sealed class DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> 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);
}
}
}
De gehoste service maakt een bereik om de scoped achtergrondservice om de methode aan te roepen DoWorkAsync
. DoWorkAsync
geeft als resultaat een Task
, die in het ExecuteAsync
volgende wordt gewacht:
De werkrolklasse herschrijven
Vervang de bestaande Worker
klasse door de volgende C#-code en wijzig de naam van het bestand in ScopedBackgroundService.cs:
namespace App.ScopedService;
public sealed class ScopedBackgroundService(
IServiceScopeFactory serviceScopeFactory,
ILogger<ScopedBackgroundService> 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<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is stopping.", ClassName);
await base.StopAsync(stoppingToken);
}
}
In de voorgaande code wordt een expliciet bereik gemaakt en wordt de IScopedProcessingService
implementatie omgezet vanuit de factory voor het bereik van de afhankelijkheidsinjectieservice. Het opgeloste service-exemplaar is binnen het bereik en DoWorkAsync
de bijbehorende methode wordt verwacht.
Vervang de inhoud van het bestand template Program.cs door de volgende C#-code:
using App.ScopedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();
IHost host = builder.Build();
host.Run();
De services worden geregistreerd in (Program.cs). De gehoste service wordt geregistreerd bij de AddHostedService
extensiemethode.
Zie Afhankelijkheidsinjectie in .NET voor meer informatie over het registreren van services.
Servicefunctionaliteit controleren
Als u de toepassing vanuit Visual Studio wilt uitvoeren, selecteert u F5 of selecteert u de menuoptie Foutopsporing> starten. Als u de .NET CLI gebruikt, voert u de dotnet run
opdracht uit vanuit de werkmap:
dotnet run
Zie dotnet run voor meer informatie over de .NET CLI-run-opdracht.
Laat de toepassing een beetje uitvoeren om verschillende stappen voor het aantal uitvoeringen te genereren. De uitvoer ziet er ongeveer als volgt uit:
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.
Als u de toepassing vanuit Visual Studio uitvoert, selecteert u Foutopsporing>stoppen.... U kunt ook Ctrl + C selecteren in het consolevenster om annulering te signaleren.