0Pricing
C# Academy · Урок

Взаимодействие компонентов и DI

Передавайте данные между родительскими и дочерними компонентами, используйте каскадные параметры и внедряйте службы в компоненты.

«Взаимодействие компонентов и DI» — бесплатный урок C# Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Шаблоны взаимодействия компонентов

Компоненты Blazor взаимодействуют в трёх направлениях: от родителя к дочернему компоненту (параметры), от дочернего компонента к родителю (EventCallback) и между узлами дерева (CascadingParameters или общие службы через DI).

От родителя к дочернему компоненту: параметры

Пометьте свойство компонента атрибутом [Parameter], чтобы родитель мог задавать его значение. Родитель передаёт значения как атрибуты HTML в теге компонента.

@* 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." />

От дочернего компонента к родителю: EventCallback

Дочерний компонент предоставляет параметр EventCallback. Родитель передаёт метод-обработчик. Дочерний компонент вызывает его, когда что-либо происходит.

@* 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>

Взаимодействие компонентов-братьев через родителя

Чтобы компоненты-братья могли взаимодействовать, передавайте данные через общего родителя. Родитель хранит общее состояние и передаёт его дочерним компонентам в виде параметров.

@* 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 *@

Каскадные параметры

Оберните поддерево в <CascadingValue>, чтобы передать данные всем потомкам и не передавать их через каждый промежуточный компонент.

@* 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>

Внедрение служб с помощью @inject

Используйте директиву @inject, чтобы напрямую внедрять в компоненты зарегистрированные службы DI. Среда выполнения разрешает их зависимости автоматически.

@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}");
}

Службы с областью действия в Blazor Server

В Blazor Server область действия DI длится весь срок подключения SignalR — не только время одного запроса. Помните, что службы с областью действия являются общими для всех компонентов одного контура.

// 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 для маршрутизации

Внедрите NavigationManager, чтобы программно переходить между страницами, читать текущий URL и обрабатывать события навигации.

@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 в Blazor WASM

В Blazor WebAssembly внедрите предварительно настроенный HttpClient для вызова API. Зарегистрируйте его с базовым адресом в 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();
    }
}

Практический пример: служба контекста пользователя

Служба с областью действия UserContextService внедряется в несколько компонентов приложения — каждый из них видит одни и те же данные пользователя без передачи параметров через цепочку компонентов.

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>

Быстрая проверка

Как долго действует DI-сервис с областью действия в Blazor Server?

Итоги: взаимодействие компонентов и DI

Основные выводы:

  • От родителя к дочернему компоненту: свойства [Parameter]; [EditorRequired] для обязательных параметров
  • От дочернего компонента к родителю: EventCallback; автоматически вызывает StateHasChanged у родителя
  • Компоненты-братья: передавайте данные через состояние родителя или используйте общую службу DI
  • Между узлами дерева: CascadingValue/CascadingParameter для глубоких поддеревьев
  • @inject для служб; службы с областью действия в Blazor Server действуют в течение всего контура
  • NavigationManager для программной маршрутизации

Часто задаваемые вопросы

Урок «Взаимодействие компонентов и DI» бесплатный?

Да — полный текст урока «Взаимодействие компонентов и DI» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Взаимодействие компонентов и DI»?

Передавайте данные между родительскими и дочерними компонентами, используйте каскадные параметры и внедряйте службы в компоненты. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Взаимодействие компонентов и DI»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Модель компонентов Blazor
  2. Привязка данных и обработка событий
  3. Взаимодействие компонентов и DI
  4. Управление состоянием в Blazor
← Назад к C# Academy