## Wstęp merytoryczny: Wbudowane wstrzykiwanie zależności pod kontrolą Hosta

Przejście z architektury **.NET Framework 4.8** na nowoczesny ekosystem **.NET 10** wymusza zmianę sposobu zarządzania cyklem życia obiektów i ich zależnościami. W klasycznych aplikacjach desktopowych (WPF, WinForms) wstrzykiwanie zależności (Dependency Injection, DI) było mechanizmem opcjonalnym, często dodawanym za pomocą zewnętrznych bibliotek (np. Autofac, Ninject). W architekturze ASP.NET Core wbudowane wstrzykiwanie zależności stanowi nierozerwalny fundament platformy.

Centralnym punktem zarządzającym wstrzykiwaniem zależności jest **Generic Host** (Host Ogólny), najczęściej powoływany za pomocą instancji `WebApplicationBuilder`. Host hermetyzuje wszystkie zasoby aplikacji: serwer HTTP, konfigurację, potok oprogramowania pośredniczącego (Middleware) oraz centralny kontener DI. Oznacza to, że w środowisku webowym to nie system operacyjny Windows ani kod interfejsu użytkownika zarządza pamięcią obiektów, lecz wysoce zoptymalizowana infrastruktura Hosta.

## Analiza Porównawcza: Zarządzanie zależnościami (Desktop vs Web)

| **Koncepcja Desktop (.NET 4.8)** | **Odpowiednik w .NET 10 (Generic Host)** | **Charakter zmiany architektonicznej** |
| --- | --- | --- |
| **Ręczne powoływanie obiektów (`new`)** | **Kontener DI (`builder.Services`)** | Odrzucenie ścisłego powiązania (tight coupling). Aplikacja polega na odwróceniu kontroli (IoC), a Host wstrzykuje instancje do konstruktorów. |
| **Zmienne statyczne / Wzorzec Singleton** | **Rejestracja o cyklu życia (Singleton/Scoped)** | Eliminacja globalnego stanu aplikacji (Stateful) na rzecz zarządzania bytem obiektów w obrębie cyklu życia bezstanowego żądania HTTP (Stateless). |
| **Zewnętrzne biblioteki DI** | **Wbudowane `Microsoft.Extensions.DependencyInjection`** | Standaryzacja. Mechanizm DI jest zintegrowany bezpośrednio wewnątrz Hosta i dostarczany natywnie przez framework. |
| **Ścisłe zależności między warstwami** | **Wstrzykiwanie przez konstruktor lub `@inject`** | Logika biznesowa jest przekazywana do nowoczesnych kontrolerów lub komponentów Blazor wyłącznie przez mechanizmy wbudowane w platformę. |

### Głębokie Nurkowanie (Deep Dive): Anatomia DI w Generic Host

W modelu ASP.NET Core proces inicjalizacji i orkiestracji działania aplikacji opiera się na dwóch fazach budowy Hosta. W fazie początkowej obiekt `WebApplicationBuilder` udostępnia właściwość `Services` reprezentującą kolekcję usług (`IServiceCollection`). To na tym etapie infrastruktura dodaje logikę dostępu do bazy danych, logowania, autoryzacji oraz renderowania komponentów interfejsu. 

Kiedy programista wywołuje metodę `builder.Build()`, Host zatrzaskuje konfigurację, generuje docelowy kontener DI (`IServiceProvider`) i konfiguruje środowisko uruchomieniowe wraz z wieloplatformowym serwerem HTTP Kestrel. Od tego momentu każda składowa potoku Middleware, każdy kontroler oraz każdy komponent Blazor otrzymuje swoje zależności wyłącznie w sposób automatyczny na etapie wykonania. Model ten eliminuje narzut związany z manualnym przekazywaniem parametrów systemowych w głąb drzewa wywołań.

## Dobre Praktyki i Antywzorce

* **Antywzorzec: Ręczna rezolucja usług:** Pobieranie instancji poprzez anty-wzorzec *Service Locator* (np. bezpośrednie odpytywanie `ServiceProvider` w warstwie logiki) łamie spójność kontroli sprawowanej przez Hosta i ogranicza przejrzystość.
* **Dobra Praktyka: Wstrzykiwanie przez konstruktor (Constructor Injection):** Zależności powinny być zawsze deklarowane jawnie jako parametry konstruktora (lub poprzez dyrektywę `@inject` w plikach `.razor`). Gwarantuje to testowalność i przejrzystość wymogów danej klasy, co ułatwia zarządzanie dostarczanymi zależnościami.

## Laboratorium kodu: Rejestracja usług i ich użycie w architekturze Hosta

Poniższy przykład demonstruje ewolucję inicjalizacji na poziomie punktu wejścia aplikacji. Użyto w nim wzorca Minimal API, gdzie `Generic Host` ładuje mechanizmy infrastruktury z jednego punktu, pozwalając na precyzyjne odizolowanie bazy danych od interfejsu UI.

```csharp
// Program.cs w .NET 10 (Konfiguracja Hosta)
using Microsoft.EntityFrameworkCore;
using ModernApp.Data;

// 1. Inicjalizacja Hosta i infrastruktury
var builder = WebApplication.CreateBuilder(args);

// 2. Rejestracja wbudowanego mechanizmu wstrzykiwania zależności (DI)
// Usługi środowiskowe (np. konfiguracja JSON) są dostępne od razu z poziomu Hosta
builder.Services.AddDbContextFactory<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection") 
    ?? throw new InvalidOperationException("Brak konfiguracji bazy danych."))); //

// Rejestracja frameworka komponentów i obsługi cyklu życia UI
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents(); //

// 3. Zbudowanie Hosta – zatrzaśnięcie kontenera DI
var app = builder.Build(); //

// (Konfiguracja bezstanowego potoku Middleware...)
app.UseHttpsRedirection(); //
app.UseAntiforgery(); //

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode(); //

// 4. Start Hosta i serwera Kestrel
app.Run(); //
```

Zastosowanie wstrzykniętych zasobów w asynchronicznym środowisku webowym za pomocą dedykowanej dyrektywy frameworka:

```html
@* TasksList.razor *@
@page "/tasks"
@using ModernApp.Data
@using Microsoft.EntityFrameworkCore

@* Deklaratywne żądanie wstrzyknięcia usługi utrzymywanej przez Generic Host *@
@inject IDbContextFactory<AppDbContext> DbFactory 

<div class="task-board">
    @if (_tasks == null)
    {
        <p><em>Pobieranie danych ze strumienia DI...</em></p>
    }
    else
    {
        <table class="table">
            @foreach (var task in _tasks)
            {
                <tr>
                    <td>@task.Title</td>
                </tr>
            }
        </table>
    }
</div>

@code {
    private List<TaskDto>? _tasks;

    // Metoda cyklu życia, w której asynchronicznie zużywamy zasoby dostarczone z Hosta
    protected override async Task OnInitializedAsync()
    {
        await using var context = DbFactory.CreateDbContext();
        _tasks = await context.Tasks.ToListAsync();
    }
}
```

## Wnioski architektoniczne

Przesunięcie zarządzania bytem i instancjonowaniem obiektów z poziomu kodu sterowanego zdarzeniami w architekturze Desktop (np. powiązanej z cyklem życia kontrolki w WPF), bezpośrednio do wbudowanego, centralnego mechanizmu kontenera DI zintegrowanego z modelem **Generic Host**, pozwala na radykalne podniesienie testowalności i skalowalności. Architektura w .NET 10 zapobiega wyciekom pamięci dzięki standaryzowanym cyklom życia obiektów (Transient, Scoped, Singleton) zarządzanym i powiązanym z ramami czasowymi żądań HTTP przetwarzanych przez Middleware. Umożliwia to zwinne budowanie i wdrażanie odseparowanej, ustandaryzowanej logiki aplikacji.