0Pricing
C# Academy · Lekcja

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 package

W 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

  1. Podstawy kontenera DI
  2. Czas życia usług: Transient, Scoped, Singleton
  3. Wstrzykiwanie przez konstruktor i interfejsy
  4. Wzorce Factory i Options
← Powrót do C# Academy