Podstawy kontenera DI
Poznaj odwrócenie sterowania, rejestrowanie usług oraz sposób, w jaki kontener DI platformy .NET rozwiązuje zależności.
Podstawy kontenera DI to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Czym jest wstrzykiwanie zależności
Wstrzykiwanie zależności (DI) to wzorzec projektowy, w którym klasa otrzymuje swoje zależności ze źródła zewnętrznego zamiast tworzyć je samodzielnie.
Zamiast pisać var repo = new UserRepository(); wewnątrz klasy, klasa deklaruje, czego potrzebuje, a kontener DI dostarcza te zależności.
Odwrócenie sterowania
DI jest konkretną implementacją zasady odwrócenia sterowania (IoC): odpowiedzialność za tworzenie zależności zostaje przeniesiona z klasy zależnej do zewnętrznego kontenera.
Dzięki temu klasy łatwiej testować i zastępować.
Konfigurowanie kontenera DI platformy .NET
W aplikacji .NET kontener DI konfiguruje się za pomocą IServiceCollection w pliku Program.cs. Usługi są rejestrowane, a następnie rozwiązywane przez środowisko uruchomieniowe.
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();
var app = builder.Build();
app.Run();Definiowanie interfejsu i implementacji
DI działa najlepiej, gdy programuje się z użyciem interfejsów. Należy zdefiniować interfejs opisujący kontrakt usługi oraz konkretną klasę, która go implementuje.
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" };
}
}Rozwiązywanie usług za pomocą konstruktora
Kontener automatycznie wstrzykuje zarejestrowane usługi do konstruktorów. Klasa musi jedynie zadeklarować potrzebny interfejs — nie jest wymagane użycie słowa kluczowego new.
public class UserService
{
private readonly IUserRepository _repo;
public UserService(IUserRepository repo)
{
_repo = repo;
}
public User? FindUser(int id) => _repo.GetById(id);
}Rejestrowanie wielu usług
Można zarejestrować dowolną liczbę potrzebnych usług. Typowe metody rozszerzające to AddTransient, AddScoped i AddSingleton — każda z nich definiuje inny czas życia usługi.
builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();Bezpośrednie używanie IServiceProvider
W rzadkich przypadkach konieczne jest imperatywne rozwiązywanie usług. IServiceProvider pozwala wywołać GetRequiredService<T>() w celu rozwiązania usługi, ale w większości scenariuszy należy preferować wstrzykiwanie przez konstruktor.
// 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);
}
}Rejestrowanie otwartych typów generycznych
.NET DI obsługuje rejestracje otwartych typów generycznych. Można jednokrotnie zarejestrować IRepository<>, a następnie rozwiązywać je jako Repository<T> dla dowolnego typu encji.
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>Walidacja podczas uruchamiania
Za pomocą ValidateOnStart() lub ValidateScopes = true kontener może wykryć nieprawidłowo skonfigurowane rejestracje, takie jak przechwycenie usługi Scoped wewnątrz usługi Singleton, podczas uruchamiania aplikacji, a nie dopiero w czasie działania.
builder.Services.AddScoped<IMyService, MyService>();
// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true;
options.ValidateOnBuild = true;
});Dekorowanie usług
Usługę można opakować dekoratorem bez modyfikowania oryginalnej klasy. Najpierw należy zarejestrować usługę wewnętrzną, a następnie dekorator, który ją opakowuje.
builder.Services.AddScoped<IUserRepository, UserRepository>();
// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet packageW praktyce: Minimal API z DI
W Minimal API usługi są wstrzykiwane bezpośrednio do parametrów procedur obsługi tras. Kontener rozwiązuje je automatycznie.
app.MapGet("/users/{id}", (int id, UserService svc) =>
{
var user = svc.FindUser(id);
return user is null ? Results.NotFound() : Results.Ok(user);
});Szybkie sprawdzenie
Jaką metodę należy preferować w większości klas do uzyskiwania zależności?
Podsumowanie: podstawy kontenera DI
Najważniejsze informacje:
- DI odwraca proces tworzenia zależności: obiekty tworzy kontener, a nie sama klasa
- Usługi rejestruje się za pomocą AddTransient / AddScoped / AddSingleton
- Wstrzykiwanie przez konstruktor jest standardowym i preferowanym podejściem
- Otwarte typy generyczne, dekoratory i ValidateOnBuild to zaawansowane, potężne funkcje
Często zadawane pytania
Czy lekcja „Podstawy kontenera DI” jest bezpłatna?
Tak — pełny tekst „Podstawy kontenera DI” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Podstawy kontenera DI”?
Poznaj odwrócenie sterowania, rejestrowanie usług oraz sposób, w jaki kontener DI platformy .NET rozwiązuje zależności. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Podstawy kontenera DI”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy kontenera DI
- Czas życia usług: Transient, Scoped, Singleton
- Wstrzykiwanie przez konstruktor i interfejsy
- Wzorce Factory i Options