0Pricing
C# Academy · Lezione

Comunicazione tra componenti e DI

Passi dati tra componenti padre e figlio, usi parametri a cascata e inietti servizi nei componenti.

Comunicazione tra componenti e DI è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Pattern di comunicazione tra componenti

I componenti Blazor comunicano in tre direzioni: dal genitore al figlio (Parameters), dal figlio al genitore (EventCallback) e attraverso l'albero (CascadingParameters o servizi condivisi tramite DI).

Dal genitore al figlio: Parameters

Decori una proprietà del componente con [Parameter] per renderla impostabile dal componente genitore. Il genitore passa i valori come attributi HTML nel tag del componente.

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

Dal figlio al genitore: EventCallback

Un componente figlio espone un parametro EventCallback. Il genitore fornisce un metodo gestore. Il figlio lo invoca quando si verifica un evento.

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

Comunicazione tra componenti fratelli tramite il genitore

Per far comunicare componenti fratelli, faccia passare i dati attraverso il genitore comune. Il genitore conserva lo stato condiviso e lo passa ai figli come parametro.

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

Parametri a cascata

Avvolga un sottoalbero in <CascadingValue> per passare i dati a tutti i discendenti senza doverli propagare attraverso ogni componente intermedio.

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

Iniezione dei servizi con @inject

Utilizzi la direttiva @inject per iniettare direttamente nei componenti i servizi DI registrati. Il framework li risolve automaticamente.

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

Servizi scoped in Blazor Server

In Blazor Server, l'ambito DI dura per l'intera durata della connessione SignalR, non solo per una singola richiesta. Tenga presente che i servizi scoped sono condivisi da tutti i componenti di un circuito.

// 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 per il routing

Inietti NavigationManager per eseguire la navigazione a livello programmatico, leggere l'URL corrente e gestire gli eventi di navigazione.

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

In Blazor WebAssembly, inietti un HttpClient preconfigurato per chiamare la propria API. Lo registri con un indirizzo di base in 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();
    }
}

Caso reale: servizio per il contesto utente

Un UserContextService scoped viene iniettato in più componenti dell'app: ciascuno vede gli stessi dati dell'utente senza dover propagare le props attraverso la gerarchia.

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>

Verifica rapida

In Blazor Server, quanto dura il ciclo di vita di un servizio DI «scoped»?

Riepilogo: comunicazione tra componenti e DI

Punti chiave:

  • Genitore → figlio: proprietà [Parameter]; [EditorRequired] per i parametri obbligatori
  • Figlio → genitore: EventCallback; attiva automaticamente StateHasChanged nel genitore
  • Fratelli: passaggio attraverso lo stato del genitore o utilizzo di un servizio DI condiviso
  • Attraverso l'albero: CascadingValue/CascadingParameter per i sottoalberi profondi
  • @inject per i servizi; in Blazor Server i servizi scoped durano per tutto il ciclo di vita del circuito
  • NavigationManager per il routing a livello programmatico

Domande Frequenti

La lezione «Comunicazione tra componenti e DI» è gratuita?

Sì — il testo completo di «Comunicazione tra componenti e DI» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Comunicazione tra componenti e DI»?

Passi dati tra componenti padre e figlio, usi parametri a cascata e inietti servizi nei componenti. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Comunicazione tra componenti e DI»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Modello dei componenti Blazor
  2. Data binding e gestione degli eventi
  3. Comunicazione tra componenti e DI
  4. Gestione dello stato in Blazor
← Torna a C# Academy