Delen via


Gebruik scoped services binnen een BackgroundService

Wanneer u implementaties met IHostedService registreert door gebruik te maken 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 Levensduur van de service voor meer informatie.

In deze handleiding leer je hoe je:

Aanbeveling

Alle voorbeeldbroncode 'Workers in .NET' is beschikbaar in de Samples Browser voor downloaden. Zie voor meer informatie Blader door codevoorbeelden: Workers in .NET.

Vereiste voorwaarden

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". Selecteer vervolgens de Worker Service-sjabloon. Als u liever de .NET CLI gebruikt, opent u uw favoriete terminal in een werkmap. Voer de opdracht dotnet new uit en vervang de <Project.Name> door de gewenste projectnaam.

dotnet new worker --name <Project.Name>

Voor meer informatie over de opdracht 'dotnet new worker' service in de .NET CLI, zie dotnet new worker.

Aanbeveling

Als u Visual Studio Code gebruikt, kunt u .NET CLI-opdrachten uitvoeren vanuit de geïntegreerde terminal. Zie Visual Studio Code: Integrated Terminalvoor meer informatie.

Gescopeerde services maken

Als u scoped services binnen een BackgroundServicewilt gebruiken, maakt u een bereik met de IServiceScopeFactory.CreateScope() API. Standaard wordt er geen scope gecreëerd 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. Maak een implementatie in een nieuwe klasse met de naam DefaultScopedProcessingService.cs:

namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private readonly string _instanceId = Guid.NewGuid().ToString();

    public Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{ServiceName} doing work, instance ID: {Id}",
            nameof(DefaultScopedProcessingService),
            _instanceId);

        return Task.CompletedTask;
    }
}
  • Een ILogger wordt in de service geïnjecteerd met behulp van een primaire constructor.
  • De DoWorkAsync methode retourneert een Task en accepteert de CancellationToken.
    • Met de methode wordt de exemplaar-id geregistreerd. De _instanceId id wordt toegewezen wanneer de klasse wordt geïnstantieerd.

De Worker-klasse 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);

        while (!stoppingToken.IsCancellationRequested)
        {
            using IServiceScope scope = serviceScopeFactory.CreateScope();

            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);

            await Task.Delay(10_000, stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is stopping.", ClassName);

        await base.StopAsync(stoppingToken);
    }
}

In de voorgaande code wordt, hoewel de stoppingToken niet wordt geannuleerd, de IServiceScopeFactory gebruikt om een bereik te maken. Vanaf de IServiceScope, is het IScopedProcessingService opgelost. De DoWorkAsync-methode wordt afgewacht, en de stoppingToken wordt aan de methode doorgegeven. Ten slotte wordt de uitvoering 10 seconden vertraagd en wordt de lus voortgezet. Telkens wanneer de DoWorkAsync methode wordt aangeroepen, wordt er een nieuw exemplaar van de DefaultScopedProcessingService methode gemaakt en wordt de exemplaar-id geregistreerd.

Vervang de sjabloon Program.cs bestandsinhoud 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 .NETvoor 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 even draaien om verschillende aanroepen te genereren naar DoWorkAsync, waardoor nieuwe exemplaar-id's worden geregistreerd. U ziet uitvoer die vergelijkbaar is met de volgende logboeken:

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
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 doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
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.

Zie ook