0Pricing
C# Academy · Lektion

Lebensdauern von Diensten: Transient, Scoped, Singleton

Lernen Sie, wie sich die Lebensdauern Transient, Scoped und Singleton auf Objekterstellung, gemeinsame Nutzung und Freigabe auswirken.

Lebensdauern von Diensten: Transient, Scoped, Singleton ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum Lebensdauern wichtig sind

Die Lebensdauer eines Dienstes bestimmt, wie lange eine Instanz lebt und wie viele Instanzen erstellt werden. Die Wahl der falschen Lebensdauer verursacht schwer erkennbare Fehler, etwa Datenlecks zwischen Anfragen oder die übermäßige Erstellung von Objekten.

Transient: Bei jeder Anforderung neu

Transient-Dienste werden jedes Mal neu erstellt, wenn sie beim Container angefordert werden. Verwenden Sie sie für leichte, zustandslose Dienste, bei denen das Teilen von Zuständen problematisch wäre.

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: Einmal pro Anfrage

Scoped-Dienste werden einmal pro Scope erstellt – in ASP.NET Core normalerweise einmal pro HTTP-Anfrage. Innerhalb einer Anfrage wird dieselbe Instanz verwendet, für die nächste Anfrage jedoch eine neue erstellt.

builder.Services.AddScoped<AppDbContext>();

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

Singleton: Eine Instanz für die Lebensdauer der Anwendung

Singleton-Dienste werden einmal erstellt und während der gesamten Lebensdauer der Anwendung wiederverwendet. Verwenden Sie sie für aufwendig zu erstellende, threadsichere Dienste wie Konfigurations-Caches.

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

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

Alle drei vergleichen

Ein schneller direkter Vergleich:

  • Transient – bei jeder Anforderung eine neue Instanz; zustandslose Hilfsfunktionen
  • Scoped – eine Instanz pro HTTP-Anfrage; DbContext, Unit of Work
  • Singleton – eine Instanz für die Lebensdauer der Anwendung; Caches, Konfigurationen

Das Problem der gefangenen Abhängigkeit

Das Injizieren eines Scoped- oder Transient-Dienstes in ein Singleton ist ein häufiger Fehler. Das Singleton hält eine Referenz auf den kurzlebigen Dienst und sorgt dadurch dafür, dass dieser zu lange aktiv bleibt.

// 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
}

Scope-Verstöße erkennen

Aktivieren Sie ValidateScopes, damit der Container beim Start eine Ausnahme auslöst, wenn eine gefangene Abhängigkeit erkannt wird. So werden Fehler erkannt, bevor sie in der Produktion zu Datenproblemen führen.

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

Scoped-Dienste außerhalb einer Anfrage

Um Scoped-Dienste in einer Hintergrundaufgabe aufzulösen, erstellen Sie mit IServiceScopeFactory einen expliziten Scope. Lösen Sie Scoped-Dienste niemals direkt aus dem Root-Container auf.

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 disposable Dienste

Transiente IDisposable-Dienste, die aus dem Root-Container aufgelöst werden, bleiben bis zur Freigabe des Containers – also bis zum Herunterfahren der Anwendung – registriert. Lösen Sie sie innerhalb eines Scopes auf, damit Ressourcen zeitnah freigegeben werden.

// 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

Die richtige Lebensdauer auswählen

Eine einfache Entscheidungshilfe:

  • Ist der Dienst zustandslos? → Transient
  • Hängt er von einer Anfrage ab, etwa von der Benutzeridentität oder dem DbContext? → Scoped
  • Ist er threadsicher und aufwendig zu erstellen? → Singleton

Praxisbeispiel: Drei Lebensdauern gemeinsam

Eine typische Web-API registriert verschiedene Dienste mit passenden Lebensdauern, um Korrektheit und Leistung sicherzustellen.

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>();

Kurzprüfung

Welches Problem tritt auf, wenn ein Singleton-Dienst eine Referenz auf einen Scoped-Dienst hält?

Zusammenfassung: Lebensdauern von Diensten

Wichtige Erkenntnisse:

  • Transient: jedes Mal eine neue Instanz – geeignet für zustandslose, leichte Dienste
  • Scoped: eine Instanz pro Anfrage – DbContext, Repositories, Unit of Work
  • Singleton: eine Instanz für immer – Caches, Konfigurationen, threadsichere Hilfsfunktionen
  • Injizieren Sie niemals kurzlebige Dienste in Dienste mit längerer Lebensdauer (gefangene Abhängigkeit)
  • Verwenden Sie IServiceScopeFactory, um Scoped-Dienste in Hintergrundaufgaben aufzulösen

Häufig gestellte Fragen

Ist die Lektion „Lebensdauern von Diensten: Transient, Scoped, Singleton“ kostenlos?

Ja — der vollständige Text von „Lebensdauern von Diensten: Transient, Scoped, Singleton“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Lebensdauern von Diensten: Transient, Scoped, Singleton“?

Lernen Sie, wie sich die Lebensdauern Transient, Scoped und Singleton auf Objekterstellung, gemeinsame Nutzung und Freigabe auswirken. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Lebensdauern von Diensten: Transient, Scoped, Singleton“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen von DI-Containern
  2. Lebensdauern von Diensten: Transient, Scoped, Singleton
  3. Konstruktor-Injection und Schnittstellen
  4. Factory- und Options-Patterns
← Zurück zu C# Academy