C# Academy · Lektion

Tjenestelevetider: Transient, Scoped, Singleton

Lær, hvordan levetiderne Transient, Scoped og Singleton påvirker oprettelse, deling og frigivelse af objekter.

Lektion 2 af 413 trin

Tjenestelevetider: Transient, Scoped, Singleton er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.

Hvorfor levetider er vigtige

En tjenestes levetid bestemmer hvor længe en instans lever og hvor mange instanser der oprettes. Hvis du vælger den forkerte levetid, opstår der subtile fejl som datalæk mellem forespørgsler eller unødvendig oprettelse af objekter.

Transient: Ny hver gang

Transient-tjenester oprettes på ny, hver gang de hentes fra containeren. Brug dem til lette, tilstandsløse tjenester, hvor deling af tilstand ville være farlig.

builder.Services.AddTransient<IEmailSender, SmtpEmailSender>();

// Each resolution creates a new instance:
// var a = sp.GetRequiredService<IEmailSender>(); // new
// var b = sp.GetRequiredService<IEmailSender>(); // new (different)

Scoped: Én pr. forespørgsel

Scoped-tjenester oprettes én gang pr. omfang — typisk én HTTP-forespørgsel i ASP.NET Core. Den samme instans deles inden for en forespørgsel, men en ny oprettes til den næste forespørgsel.

builder.Services.AddScoped<AppDbContext>();

// Within a single HTTP request:
// Both resolve to the SAME AppDbContext instance
// -> consistent unit of work across the request

Singleton: Én i hele programmets levetid

Singleton-tjenester oprettes én gang og genbruges i hele programmets levetid. Brug dem til tjenester, der er dyre at oprette og trådsikre, såsom caches til konfiguration.

builder.Services.AddSingleton<IMemoryCache, MemoryCache>();

// Or register a pre-built instance:
var config = new AppConfig { MaxRetries = 3 };
builder.Services.AddSingleton<IAppConfig>(config);

Sammenligning af alle tre

En hurtig sammenligning:

  • Transient — ny instans ved hver forespørgsel; tilstandsløse hjælpeværktøjer
  • Scoped — én pr. HTTP-forespørgsel; DbContext, arbejdsenhed
  • Singleton — én i hele programmets levetid; cacher, konfigurationer

Problemet med fastholdte afhængigheder

Det er en almindelig fejl at injicere en Scoped- eller Transient-tjeneste i en Singleton. Singleton-tjenesten holder en reference til den kortlivede tjeneste og holder den dermed i live for længe.

// BAD: Singleton captures a Scoped service
public class MySingleton
{
    private readonly AppDbContext _db; // Scoped!
    public MySingleton(AppDbContext db) => _db = db;
    // _db is now stuck alive for the app's lifetime
}

Registrering af fejl i tjenesteområder

Aktivér ValidateScopes, så containeren kaster en fejl ved opstart, hvis der registreres en fastholdt afhængighed. Det fanger fejl, før de giver anledning til dataproblemer i produktion.

builder.Host.UseDefaultServiceProvider(options =>
{
    options.ValidateScopes = true;   // detect captive deps
    options.ValidateOnBuild = true;  // fail fast at start
});

Scoped-tjenester uden for en forespørgsel

For at hente Scoped-tjenester i en baggrundsopgave skal du oprette et eksplicit omfang med IServiceScopeFactory. Hent aldrig Scoped-tjenester direkte fra rodcontaineren.

public class MyWorker : BackgroundService
{
    private readonly IServiceScopeFactory _factory;

    public MyWorker(IServiceScopeFactory factory) => _factory = factory;

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        using var scope = _factory.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        await db.Users.ToListAsync(ct);
    }
}

Transiente tjenester, der kan bortskaffes

Transiente IDisposable-tjenester, der hentes fra rodcontaineren, spores, indtil containeren bortskaffes (når programmet lukker). Hent dem inden for et omfang for at frigive ressourcer hurtigt.

// Correctly scoped transient disposable
using var scope = sp.CreateScope();
var svc = scope.ServiceProvider.GetRequiredService<MyDisposableService>();
await svc.DoWorkAsync();
// svc.Dispose() called when scope is disposed

Valg af den rigtige levetid

En enkel beslutningsguide:

  • Er tjenesten tilstandsløs? → Transient
  • Afhænger den af en forespørgsel (f.eks. brugeridentitet eller DbContext)? → Scoped
  • Er den trådsikker og dyr at oprette? → Singleton

Praktisk eksempel: Tre levetider sammen

En typisk web-API registrerer forskellige tjenester med passende levetider for at sikre korrekthed og ydeevne.

builder.Services.AddSingleton<IConfiguration>(builder.Configuration);
builder.Services.AddSingleton<ICacheService, RedisCacheService>();

builder.Services.AddScoped<AppDbContext>();
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<OrderService>();

builder.Services.AddTransient<IEmailSender, SendGridEmailSender>();

Hurtigt tjek

Hvilket problem opstår, når en Singleton-tjeneste holder en reference til en Scoped-tjeneste?

Opsummering: Tjenesternes levetider

Vigtigste pointer:

  • Transient: ny instans hver gang — velegnet til tilstandsløse, lette tjenester
  • Scoped: én instans pr. forespørgsel — DbContext, repositories, arbejdsenheder
  • Singleton: én instans i hele programmets levetid — cacher, konfigurationer, trådsikre hjælpeværktøjer
  • Injicér aldrig kortlivede tjenester i tjenester med længere levetid (fastholdt afhængighed)
  • Brug IServiceScopeFactory til at hente Scoped-tjenester i baggrundsopgaver
Gratis at komme i gang

Lær C# med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
93
Lektioner
346

Ofte stillede spørgsmål

Er lektionen “Tjenestelevetider: Transient, Scoped, Singleton” gratis?

Ja — hele teksten til “Tjenestelevetider: Transient, Scoped, Singleton” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Tjenestelevetider: Transient, Scoped, Singleton”?

Lær, hvordan levetiderne Transient, Scoped og Singleton påvirker oprettelse, deling og frigivelse af objekter. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C# Academy?

Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Tjenestelevetider: Transient, Scoped, Singleton”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C# Academy-lektion?

Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Grundlæggende om DI-containere
  2. Tjenestelevetider: Transient, Scoped, Singleton
  3. Constructor Injection og grænseflader
  4. Factory- og Options-mønstre
← Tilbage til C# Academy