Inyección de Dependencias en Angular: Dominando Servicios y Providers
La Inyección de Dependencias (DI) es el corazón de Angular. Es el mecanismo que permite a nuestras clases recibir las herramientas que necesitan para funcionar sin tener que crearlas internamente.
¿Qué es la Inyección de Dependencias?
En términos simples, la DI es un patrón de diseño donde una clase solicita dependencias externas en lugar de instanciarlas ella misma. En Angular, esto se logra a través del Injector, que actúa como un contenedor que sabe cómo crear y entregar estas piezas.
¿Cuándo deberías usar un Servicio?
No todo el código debe ir en los componentes. Debes extraer lógica a un servicio cuando:
- Compartir datos: Cuando varios componentes necesitan acceder a la misma información.
- Lógica de Negocio: Para mantener tus componentes 'limpios' y enfocados solo en la visualización.
- Llamadas API: Toda la interacción con el
HttpClientdebe vivir en servicios. - Encapsulamiento: Cuando quieres ocultar la complejidad de una implementación tras una interfaz sencilla.
Creación y Configuración de un Servicio
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Esto lo convierte en un Singleton disponible en toda la app
})
export class DataService {
private data = ['Angular', 'React', 'Vue'];
getData() {
return this.data;
}
}
Formas de Inyectar Dependencias
A partir de las versiones modernas de Angular, tenemos dos formas principales de inyectar servicios:
1. Vía Constructor (Tradicional)
@Component({ ... })
export class UserComponent {
constructor(private userService: UserService) {}
}
2. Función inject() (Moderna)
La función inject() es la forma recomendada en Angular moderno, especialmente útil en funciones standalone y composición de lógica.
import { inject } from '@angular/core';
@Component({ ... })
export class UserComponent {
private userService = inject(UserService);
}
El Árbol de Inyectores (Hierarchical Injection)
Una de las potencias de Angular es que los inyectores son jerárquicos:
- Root Injector: El servicio es una instancia única para toda la aplicación.
- Component Injector: Si declaras un servicio en el array
providers: []de un componente, se creará una instancia única para ese componente y sus hijos. Al destruir el componente, el servicio también se destruye.
Buenas Prácticas
- Principio de Responsabilidad Única: Un servicio debe hacer una sola cosa (ej.
AuthServicesolo para autenticación). - Evitar lógica en el Constructor: Usa el constructor o el
inject()solo para asignar dependencias. La lógica de inicialización debe ir en el hookngOnInit. - Interfaces: Siempre que sea posible, utiliza tipos claros para lo que devuelven tus servicios.
Conclusión
Dominar la Inyección de Dependencias te permite escribir código más testeable, modular y fácil de mantener. Al mover la lógica pesada a los servicios, tus componentes se vuelven piezas ligeras dedicadas exclusivamente a la experiencia de usuario.