0Pricing
C# Academy · Lekcja

Komunikacja komponentów i DI

Przekazuj dane między komponentami nadrzędnymi i podrzędnymi, używaj parametrów kaskadowych oraz wstrzykuj usługi do komponentów.

Komunikacja komponentów i DI to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 3 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.

Wzorce komunikacji komponentów

Komponenty Blazora komunikują się w trzech kierunkach: rodzic z dzieckiem (parametry), dziecko z rodzicem (EventCallback) oraz w poprzek drzewa (CascadingParameters lub współdzielone usługi za pośrednictwem DI).

Rodzic → dziecko: parametry

Oznacz właściwość komponentu atrybutem [Parameter], aby można było ustawiać jej wartość z poziomu rodzica. Rodzic przekazuje wartości jako atrybuty HTML w znaczniku komponentu.

@* Child: Alert.razor *@
<div class="alert alert-@Type">
    @Message
</div>

@code {
    [Parameter] public string Type { get; set; } = "info"; // primary, warning, danger
    [Parameter, EditorRequired] public string Message { get; set; } = "";
}

@* Parent usage: *@
<Alert Type="danger" Message="Something went wrong!" />
<Alert Message="Record saved." />

Dziecko → rodzic: EventCallback

Komponent potomny udostępnia parametr EventCallback. Rodzic przekazuje metodę obsługi zdarzenia. Komponent potomny wywołuje ją, gdy coś się wydarzy.

@* Child: QuantityPicker.razor *@
<button @onclick="() => OnChanged.InvokeAsync(Value - 1)">-</button>
<span>@Value</span>
<button @onclick="() => OnChanged.InvokeAsync(Value + 1)">+</button>

@code {
    [Parameter] public int Value { get; set; } = 1;
    [Parameter] public EventCallback<int> OnChanged { get; set; }
}

@* Parent: *@
<QuantityPicker Value="@_qty" OnChanged="q => _qty = q" />
<p>Quantity: @_qty</p>

Komunikacja rodzeństwa za pośrednictwem rodzica

Aby komponenty będące rodzeństwem mogły się komunikować, należy przekazywać dane przez wspólnego rodzica. Rodzic przechowuje współdzielony stan i przekazuje go dzieciom jako parametry.

@* Parent holds shared state *@
<CategoryFilter OnChanged="c => _category = c" />
<ProductList Category="_category" />

@code {
    private string _category = "All";
}

@* CategoryFilter raises an event -> Parent updates _category
   -> ProductList re-renders with new Category *@

Parametry kaskadowe

Owiń poddrzewo w <CascadingValue>, aby przekazać dane wszystkim elementom potomnym bez przekazywania ich przez każdy komponent pośredni.

@* Wrap a subtree *@
<CascadingValue Value="_theme">
    <MainLayout />
</CascadingValue>

@code { private Theme _theme = new Theme { PrimaryColor = "#6366f1" }; }

@* Any descendant can receive it: *@
@code {
    [CascadingParameter]
    public Theme AppTheme { get; set; } = default!;
}

<h1 style="color: @AppTheme.PrimaryColor">Hello</h1>

Wstrzykiwanie usług za pomocą @inject

Użyj dyrektywy @inject, aby wstrzykiwać zarejestrowane usługi DI bezpośrednio do komponentów. Framework automatycznie je rozwiązuje.

@inject IProductService ProductSvc
@inject ILogger<ProductList> Logger
@inject NavigationManager Nav

@code {
    private List<Product> _products = new();

    protected override async Task OnInitializedAsync()
    {
        Logger.LogInformation("Loading products");
        _products = await ProductSvc.GetAllAsync();
    }

    private void GoToProduct(int id)
        => Nav.NavigateTo($"/products/{id}");
}

Usługi scoped w Blazor Server

W Blazor Server zakres DI trwa przez cały czas życia połączenia SignalR — nie tylko przez pojedyncze żądanie. Należy pamiętać, że usługi scoped są współdzielone przez wszystkie komponenty w obwodzie.

// Blazor Server: scoped = per circuit (connection lifetime)
builder.Services.AddScoped<CartService>();
// All components in the same browser tab share the SAME CartService

// This is GOOD for cart state (user's items persist across pages)
// This is BAD for request-scoped data — treat as session-like scope

// For true per-render-cycle scope, create your own:
using var scope = ScopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();

NavigationManager do routingu

Wstrzyknij NavigationManager, aby programowo nawigować, odczytywać bieżący adres URL i obsługiwać zdarzenia nawigacji.

@inject NavigationManager Nav

@code {
    private void GoHome()         => Nav.NavigateTo("/");
    private void GoToProduct(int id) => Nav.NavigateTo($"/products/{id}");
    private void ForceReload()    => Nav.NavigateTo("/", forceLoad: true);

    protected override void OnInitialized()
    {
        // Read current URL
        var uri = Nav.Uri;
        var path = new Uri(uri).AbsolutePath;
    }
}

HttpClient w Blazor WASM

W Blazor WebAssembly wstrzyknij wstępnie skonfigurowany HttpClient, aby wywoływać swoje API. Zarejestruj go z adresem bazowym w pliku Program.cs.

// Program.cs (Blazor WASM)
builder.Services.AddScoped(sp => new HttpClient
{
    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});

// Component:
@inject HttpClient Http

@code {
    private List<Product> _products = new();

    protected override async Task OnInitializedAsync()
    {
        _products = await Http.GetFromJsonAsync<List<Product>>("/api/products")
                   ?? new();
    }
}

Praktyczny przykład: usługa kontekstu użytkownika

Usługa scoped UserContextService jest wstrzykiwana do wielu komponentów w całej aplikacji — każdy z nich widzi te same dane użytkownika bez prop-drillingu.

public class UserContextService
{
    public string? Name { get; private set; }
    public bool IsAdmin { get; private set; }

    public async Task InitializeAsync(AuthenticationState auth)
    {
        var user = auth.User;
        Name = user.Identity?.Name;
        IsAdmin = user.IsInRole("Admin");
    }
}

// Registered as scoped:
builder.Services.AddScoped<UserContextService>();

// Used in any component:
@inject UserContextService UserCtx
<p>Hello, @UserCtx.Name @(UserCtx.IsAdmin ? "(Admin)" : "")</p>

Szybkie sprawdzenie

Jak długo w Blazor Server trwa czas życia usługi DI o zakresie 'scoped'?

Podsumowanie: komunikacja komponentów i DI

Najważniejsze informacje:

  • Rodzic → dziecko: właściwości [Parameter]; [EditorRequired] dla wymaganych parametrów
  • Dziecko → rodzic: EventCallback; automatycznie wywołuje StateHasChanged w rodzicu
  • Rodzeństwo: przekazywanie przez stan rodzica lub użycie współdzielonej usługi DI
  • W poprzek drzewa: CascadingValue/CascadingParameter dla głębokich poddrzew
  • @inject do usług; usługi scoped w Blazor Server trwają przez czas życia obwodu
  • NavigationManager do programowego routingu

Często zadawane pytania

Czy lekcja „Komunikacja komponentów i DI” jest bezpłatna?

Tak — pełny tekst „Komunikacja komponentów i 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 „Komunikacja komponentów i DI”?

Przekazuj dane między komponentami nadrzędnymi i podrzędnymi, używaj parametrów kaskadowych oraz wstrzykuj usługi do komponentów. Ć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 3 z 4.

Ile czasu zajmuje lekcja „Komunikacja komponentów i 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. Model komponentów Blazor
  2. Wiązanie danych i obsługa zdarzeń
  3. Komunikacja komponentów i DI
  4. Zarządzanie stanem w Blazor
← Powrót do C# Academy