Grundlagen von DI-Containern
Verstehen Sie die Umkehrung der Kontrolle, die Registrierung von Diensten und wie der .NET-DI-Container Abhängigkeiten auflöst.
Grundlagen von DI-Containern ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 1 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.
Was ist Dependency Injection?
Dependency Injection (DI) ist ein Entwurfsmuster, bei dem eine Klasse ihre Abhängigkeiten von einer externen Quelle erhält, anstatt sie selbst zu erstellen.
Statt innerhalb einer Klasse var repo = new UserRepository(); zu schreiben, deklariert die Klasse, was sie benötigt, und der DI-Container stellt es bereit.
Inversion of Control
DI ist eine konkrete Umsetzung des Prinzips Inversion of Control (IoC): Die Kontrolle über das Erstellen von Abhängigkeiten wird von der abhängigen Klasse auf einen externen Container verlagert.
Das erleichtert das Testen und Austauschen von Klassen.
.NET-DI-Container einrichten
In einer .NET-App wird der DI-Container über IServiceCollection in Program.cs konfiguriert. Dienste werden registriert und anschließend von der Laufzeit aufgelöst.
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();
var app = builder.Build();
app.Run();Eine Schnittstelle und Implementierung definieren
DI funktioniert am besten, wenn Sie gegen Schnittstellen programmieren. Definieren Sie eine Schnittstelle für den Dienstvertrag und eine konkrete Klasse, die diese implementiert.
public interface IUserRepository
{
User? GetById(int id);
}
public class UserRepository : IUserRepository
{
public User? GetById(int id)
{
// fetch from database
return new User { Id = id, Name = "Alice" };
}
}Dienste über den Konstruktor auflösen
Der Container injiziert registrierte Dienste automatisch in Konstruktoren. Die Klasse muss lediglich die benötigte Schnittstelle deklarieren – das Schlüsselwort new ist nicht erforderlich.
public class UserService
{
private readonly IUserRepository _repo;
public UserService(IUserRepository repo)
{
_repo = repo;
}
public User? FindUser(int id) => _repo.GetById(id);
}Mehrere Dienste registrieren
Sie können beliebig viele benötigte Dienste registrieren. Häufig verwendete Erweiterungsmethoden sind AddTransient, AddScoped und AddSingleton> – jede definiert eine andere Lebensdauer.
builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();IServiceProvider direkt verwenden
In seltenen Fällen müssen Sie Dienste imperativ auflösen. Mit IServiceProvider können Sie GetRequiredService<T>() aufrufen, um einen Dienst aufzulösen. In den meisten Szenarien sollten Sie jedoch die Konstruktorinjektion bevorzugen.
// Anti-pattern (service locator) — use sparingly
public class ManualResolver
{
private readonly IServiceProvider _sp;
public ManualResolver(IServiceProvider sp) => _sp = sp;
public void DoWork()
{
var svc = _sp.GetRequiredService<UserService>();
svc.FindUser(1);
}
}Offene generische Typen registrieren
.NET DI unterstützt Registrierungen offener generischer Typen. Sie können IRepository<> einmal registrieren, und es wird für jeden Entitätstyp zu Repository<T> aufgelöst.
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>Validierung beim Start
Mit ValidateOnStart() oder ValidateScopes = true kann der Container falsch konfigurierte Registrierungen – beispielsweise das Festhalten eines Scoped-Dienstes in einem Singleton – beim Anwendungsstart statt erst zur Laufzeit erkennen.
builder.Services.AddScoped<IMyService, MyService>();
// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true;
options.ValidateOnBuild = true;
});Dienste dekorieren
Sie können einen Dienst mit einem Dekorator umschließen, ohne die ursprüngliche Klasse zu ändern. Registrieren Sie zuerst den inneren Dienst und anschließend den Dekorator, der ihn umschließt.
builder.Services.AddScoped<IUserRepository, UserRepository>();
// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet packagePraxisbeispiel: Minimal API mit DI
In einer Minimal API werden Dienste direkt in die Parameter des Routenhandlers injiziert. Der Container löst sie automatisch auf.
app.MapGet("/users/{id}", (int id, UserService svc) =>
{
var user = svc.FindUser(id);
return user is null ? Results.NotFound() : Results.Ok(user);
});Kurzprüfung
Welche Methode sollten Sie in den meisten Klassen zum Abrufen von Abhängigkeiten bevorzugen?
Zusammenfassung: Grundlagen des DI-Containers
Wichtige Erkenntnisse:
- DI kehrt die Erstellung von Abhängigkeiten um: Der Container erstellt Objekte, nicht die Klasse selbst
- Registrieren Sie Dienste mit AddTransient / AddScoped / AddSingleton
- Konstruktorinjektion ist der Standard und der bevorzugte Ansatz
- Offene generische Typen, Dekoratoren und ValidateOnBuild sind leistungsfähige fortgeschrittene Funktionen
Häufig gestellte Fragen
Ist die Lektion „Grundlagen von DI-Containern“ kostenlos?
Ja — der vollständige Text von „Grundlagen von DI-Containern“ 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 „Grundlagen von DI-Containern“?
Verstehen Sie die Umkehrung der Kontrolle, die Registrierung von Diensten und wie der .NET-DI-Container Abhängigkeiten auflöst. 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 1 von 4.
Wie lange dauert die Lektion „Grundlagen von DI-Containern“?
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