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 requestSingleton: 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 disposedDie 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
- Grundlagen von DI-Containern
- Lebensdauern von Diensten: Transient, Scoped, Singleton
- Konstruktor-Injection und Schnittstellen
- Factory- und Options-Patterns