0Pricing
C# Academy · レッスン

コンポーネント間通信とDI

親コンポーネントと子コンポーネントの間でデータを渡し、カスケーディングパラメーターを使い、コンポーネントにサービスを注入します。

「コンポーネント間通信とDI」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

コンポーネント間の通信パターン

Blazor コンポーネントは、3 つの方向で通信します。親から子(Parameters)、子から親(EventCallback)、そしてツリー全体(CascadingParameters または DI 経由の共有サービス)です。

親から子:Parameters

コンポーネントのプロパティに [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 の Scoped サービス

Blazor Server では、DI スコープは単一のリクエストだけでなく、SignalR 接続の存続期間全体にわたって維持されます。Scoped サービスは、1 つの circuit 内にあるすべてのコンポーネントで共有される点に注意してください。

// 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;
    }
}

Blazor WASM での HttpClient

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();
    }
}

実践例:ユーザーコンテキストサービス

Scoped な UserContextService をアプリ全体の複数のコンポーネントに注入すると、各コンポーネントが prop drilling なしで同じユーザーデータを参照できます。

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>

クイックチェック

Blazor Server では、「Scoped」DI サービスの有効期間はどのくらいですか。

まとめ:コンポーネント間通信と DI

重要なポイント:

  • 親 → 子: [Parameter] プロパティ。必須パラメーターには [EditorRequired]
  • 子 → 親:EventCallback。親の StateHasChanged を自動的にトリガー
  • 兄弟:親の状態を経由するか、共有 DI サービスを使用
  • ツリー全体:深いサブツリーには CascadingValue/CascadingParameter
  • サービスには @inject。Blazor Server の Scoped サービスは circuit の有効期間中維持
  • プログラムからのルーティングには NavigationManager

よくある質問

「コンポーネント間通信とDI」レッスンは無料ですか?

はい。「コンポーネント間通信とDI」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「コンポーネント間通信とDI」で何を学びますか?

親コンポーネントと子コンポーネントの間でデータを渡し、カスケーディングパラメーターを使い、コンポーネントにサービスを注入します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「コンポーネント間通信とDI」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Blazorコンポーネントモデル
  2. データバインディングとイベント処理
  3. コンポーネント間通信とDI
  4. Blazorの状態管理
← C# Academyに戻る