Comunicación entre componentes e DI
Pase datos entre componentes principales y secundarios, use parámetros en cascada e inyecte servicios en los componentes.
Comunicación entre componentes e DI es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.
Patrones de comunicación entre componentes
Los componentes de Blazor se comunican en tres direcciones: del padre al hijo (Parameters), del hijo al padre (EventCallback) y a través del árbol (CascadingParameters o servicios compartidos mediante DI).
Del padre al hijo: parámetros
Decore una propiedad del componente con [Parameter] para que el padre pueda establecer su valor. El padre pasa los valores como atributos HTML en la etiqueta 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." />Del hijo al padre: EventCallback
Un componente hijo expone un parámetro EventCallback. El padre proporciona un método controlador. El hijo lo invoca cuando sucede algo.
@* 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>Comunicación entre hermanos mediante el padre
Para que los componentes hermanos se comuniquen, haga pasar los datos por el padre común. El padre mantiene el estado compartido y lo pasa a los hijos como parámetros.
@* 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 *@Parámetros en cascada
Envuelva un subárbol en <CascadingValue> para pasar datos a todos sus descendientes sin tener que hacerlos pasar por cada 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>Inyección de servicios con @inject
Utilice la directiva @inject para inyectar servicios de DI registrados directamente en los componentes. El framework los resuelve automáticamente.
@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}");
}Servicios con ámbito en Blazor Server
En Blazor Server, el ámbito de DI dura toda la conexión de SignalR —no solo una solicitud—. Tenga en cuenta que los servicios con ámbito se comparten entre todos los componentes de 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 para el enrutamiento
Inyecte NavigationManager para navegar mediante código, leer la URL actual y gestionar eventos de navegación.
@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 en Blazor WASM
En Blazor WebAssembly, inyecte un HttpClient preconfigurado para llamar a su API. Regístrelo con una dirección base en 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 real: servicio de contexto de usuario
Un UserContextService con ámbito se inyecta en varios componentes de la aplicación; todos ven los mismos datos de usuario sin tener que pasar props manualmente por la jerarquía.
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>Comprobación rápida
En Blazor Server, ¿cuánto dura la duración de un servicio de DI con ámbito?
Resumen: comunicación entre componentes y DI
Conclusiones clave:
- Padre → hijo: propiedades [Parameter]; [EditorRequired] para parámetros obligatorios
- Hijo → padre: EventCallback; activa automáticamente StateHasChanged en el padre
- Hermanos: haga pasar los datos por el estado del padre o utilice un servicio de DI compartido
- A través del árbol: CascadingValue/CascadingParameter para subárboles profundos
- @inject para servicios; los servicios con ámbito de Blazor Server duran toda la vida del circuito
- NavigationManager para el enrutamiento mediante código
Preguntas frecuentes
¿La lección «Comunicación entre componentes e DI» es gratis?
Sí — el texto completo de «Comunicación entre componentes e DI» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Comunicación entre componentes e DI»?
Pase datos entre componentes principales y secundarios, use parámetros en cascada e inyecte servicios en los componentes. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C# Academy?
No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Comunicación entre componentes e DI»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C# Academy?
Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Modelo de componentes de Blazor
- Enlace de datos y gestión de eventos
- Comunicación entre componentes e DI
- Gestión de estado en Blazor