Angular 21 de Cero a Experto / Servicios y DI
Jerarquía de inyectores: dónde vive cada servicio
Hasta ahora todos tus servicios eran singletons globales (providedIn: 'root'). Pero a veces
quieres lo contrario: una instancia FRESCA por cada componente —por ejemplo, un servicio de
estado local a un formulario, o un "carrito" por cada pestaña—. Angular organiza los
inyectores en una JERARQUÍA que hace esto posible y predecible. Entenderla te da control
total sobre el alcance y el ciclo de vida de tus servicios.
Un árbol de despensas
Los niveles de la jerarquía
Instancia por componente: providers en @Component
Cuando pones un servicio en el array providers de un componente, Angular crea una instancia
nueva para ESE componente (y sus hijos), independiente del resto de la app:
import { Component } from '@angular/core';
import { BorradorService } from './borrador.service';
@Component({
selector: 'app-editor-gasto',
providers: [BorradorService], // ← una instancia NUEVA por cada <app-editor-gasto>
template: `...`,
})
export class EditorGastoComponent {
private borrador = inject(BorradorService);
// este BorradorService es SOLO de este editor: dos editores no comparten borrador
}Compáralo con el singleton: providedIn: 'root' da UNA instancia para toda la app;
providers: [X] en un componente da UNA instancia POR componente. La elección depende de si
el estado es global (root) o local a una pieza reutilizable (componente).
// GLOBAL: la lista, el resumen y el form comparten los mismos gastos
@Injectable({ providedIn: 'root' })
export class BolsilloStore {}
// LOCAL: cada tarjeta editable tiene su propio borrador aislado
@Component({ providers: [BorradorService] })
export class TarjetaEditable {}Cuándo usar cada uno
providedIn: 'root'— la mayoría de servicios: estado global, acceso a datos, lógica compartida, clientes HTTP. Es tu opción por defecto.providersen un componente — cuando cada instancia del componente necesita su PROPIO estado aislado: un formulario complejo con estado de borrador, un widget que aparece varias veces y no debe compartir datos con sus hermanos.providersen una ruta — estado que vive mientras estás en una sección de la app y se descarta al salir (lo verás en el módulo de routing).
Antes (providers en NgModule) vs Ahora (providedIn y providers standalone)
Pones `providers: [BorradorService]` en un componente que aparece 3 veces en la pantalla. ¿Cuántas instancias de BorradorService hay?
Mini-reto
Para cada caso, decide dónde proveerías el servicio (root, ruta o componente) y por qué:
- un
AuthServicecon el usuario logueado; 2) unBorradorServiceque guarda lo que escribes en un formulario de gasto antes de enviarlo; 3) unApiGastosServiceque llama al backend; 4) unWizardServiceque lleva el estado de un asistente de varios pasos que aparece en distintas pantallas.
Qué sigue
Ya controlas el ALCANCE de tus servicios. Falta un caso: ¿cómo inyectas algo que NO es una clase —una URL de configuración, un valor, una función—? Para eso están los tokens de inyección, el tema de la próxima lección, que cierra la teoría del módulo antes del reto.