Grunderna i DI-containrar
Förstå inversion of control, tjänsteregistrering och hur .NET DI-containern löser beroenden.
Grunderna i DI-containrar är en gratis lektion i C# Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för C# Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C# Academy innehåller totalt 4 lektioner.
Vad är dependency injection
Dependency injection (DI) är ett designmönster där en klass får sina beroenden från en extern källa i stället för att skapa dem själv.
I stället för att skriva var repo = new UserRepository(); i en klass deklarerar klassen vad den behöver, och DI-containern tillhandahåller det.
Inversion of Control
DI är en konkret implementering av principen Inversion of Control (IoC): kontrollen över att skapa beroenden flyttas från den beroende klassen till en extern container.
Det gör klasser enklare att testa och byta ut.
Konfigurera .NET DI-containern
I en .NET-app konfigureras DI-containern via IServiceCollection i Program.cs. Tjänster registreras och löses sedan av körningen.
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();
var app = builder.Build();
app.Run();Definiera ett gränssnitt och en implementation
DI fungerar bäst när du programmerar mot gränssnitt. Definiera ett gränssnitt för tjänstekontraktet och en konkret klass som implementerar det.
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" };
}
}Lösa upp tjänster via konstruktorn
Containern injicerar automatiskt registrerade tjänster i konstruktorer. Klassen behöver bara deklarera vilket gränssnitt den behöver – inget new-nyckelord krävs.
public class UserService
{
private readonly IUserRepository _repo;
public UserService(IUserRepository repo)
{
_repo = repo;
}
public User? FindUser(int id) => _repo.GetById(id);
}Registrera flera tjänster
Du kan registrera så många tjänster som behövs. Vanliga tilläggsmetoder är AddTransient, AddScoped och AddSingleton – var och en definierar en annan livslängd.
builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();Använda IServiceProvider direkt
I sällsynta fall behöver du lösa upp tjänster imperativt. Med IServiceProvider kan du anropa GetRequiredService<T>() för att lösa upp en tjänst, men föredra konstruktorinjektion i de flesta situationer.
// 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);
}
}Registrera öppna generiska typer
.NET DI har stöd för registrering av öppna generiska typer. Du kan registrera IRepository<> en gång, så löses det upp till Repository<T> för alla entitetstyper.
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>Validering vid programstart
Med ValidateOnStart() eller ValidateScopes = true kan containern upptäcka felaktigt konfigurerade registreringar (till exempel att en Scoped-tjänst hålls kvar av en Singleton) när programmet startar i stället för vid körning.
builder.Services.AddScoped<IMyService, MyService>();
// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true;
options.ValidateOnBuild = true;
});Dekorera tjänster
Du kan omsluta en tjänst med en dekoratör utan att ändra den ursprungliga klassen. Registrera den inre tjänsten först och registrera sedan dekoratören som omsluter den.
builder.Services.AddScoped<IUserRepository, UserRepository>();
// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet packageI praktiken: Minimal API med DI
I ett Minimal API injiceras tjänster direkt i parametrarna till route-hanterare. Containern löser automatiskt upp dem.
app.MapGet("/users/{id}", (int id, UserService svc) =>
{
var user = svc.FindUser(id);
return user is null ? Results.NotFound() : Results.Ok(user);
});Snabb kontroll
Vilken metod bör du föredra för att hämta beroenden i de flesta klasser?
Sammanfattning: Grunderna i DI-containern
Viktiga lärdomar:
- DI vänder på skapandet av beroenden: containern skapar objekten, inte klassen själv
- Registrera tjänster med AddTransient / AddScoped / AddSingleton
- Konstruktorinjektion är standardmetoden och den rekommenderade metoden
- Öppna generiska typer, dekoratörer och ValidateOnBuild är kraftfulla avancerade funktioner
Lär dig C# med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 93
- Lektioner
- 346
Vanliga frågor
Är lektionen ”Grunderna i DI-containrar” gratis?
Ja – hela texten till ”Grunderna i DI-containrar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i C# Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i C# Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Grunderna i DI-containrar”?
Förstå inversion of control, tjänsteregistrering och hur .NET DI-containern löser beroenden. Ni övar på C# Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig C# Academy?
Du behöver inga förkunskaper. Utbildningen i C# Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Grunderna i DI-containrar”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här C# Academy-lektionen?
Ja. Varje C# Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Grunderna i DI-containrar
- Tjänstelivslängder: Transient, Scoped, Singleton
- Konstruktorinjektion och gränssnitt
- Factory- och Options-mönster