En el mundo de Angular, los providers juegan un papel fundamental para el funcionamiento del sistema de inyección de dependencias (Dependency Injection o DI). Son los encargados de decirle al framework cómo y cuándo crear instancias de los servicios que los componentes, directivas o incluso otros servicios necesitarán.
Si estás empezando a trabajar con Angular, comprender este concepto te ayudará a estructurar mejor tu código, a hacerlo más eficiente y, sobre todo, mucho más mantenible.
La inyección de dependencias es un patrón de diseño que busca desacoplar la creación de los objetos (dependencias) del código que los va a utilizar. En lugar de que una clase cree sus propias dependencias, estas se inyectan, haciéndola más flexible y fácil de testear. Angular usa este patrón para crear instancias de servicios y controlarlos a través de los providers.
Un provider es, básicamente, una receta que le indica a Angular cómo crear una instancia de un servicio o cualquier otra dependencia. Existen varios tipos de providers, cada uno adecuado para diferentes situaciones.
providedIn: 'root'
, Angular crea una única instancia de este servicio, lo que lo convierte en un singleton accesible desde cualquier parte de la aplicación.@Injectable({
providedIn: 'root',
})
export class AuthService {}
useClass
: Te permite reemplazar una clase por otra. Es útil cuando necesitas proporcionar una implementación alternativa de un servicio.{ provide: MyService, useClass: MyAlternativeService }
useValue
: Permite inyectar valores constantes, como URLs o configuraciones.const API_URL = '<https://api.example.com>';
{ provide: 'API_URL', useValue: API_URL }
useFactory
: Sirve para crear dependencias de manera dinámica a través de una función. Útil si necesitas realizar alguna lógica antes de crear la instancia del servicio.{ provide: ApiService, useFactory: apiServiceFactory, deps: [AppConfig] }
useExisting
: Te permite usar un servicio ya existente bajo un nombre o alias diferente.{ provide: MyAliasService, useExisting: MyService }
Los providers pueden tener diferentes alcances (scope) dependiendo de dónde y cómo los declares. Pueden ser globales, de módulo, o locales (componente/directiva).
providedIn: 'root'
: Global, disponible en toda la aplicación.providers
de un componente, su alcance queda limitado a ese componente y sus hijos.A veces, no es suficiente usar una clase como identificador. Aquí es donde los InjectionTokens
entran en juego. Estos permiten inyectar valores o servicios con identificadores personalizados, lo que añade flexibilidad y evita conflictos.
import { InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('API_URL');
Angular optimiza la creación de servicios con lazy providers, asegurándose de que las instancias solo se crean cuando son realmente necesarias. Esto ayuda a mejorar el rendimiento de la aplicación, especialmente cuando se trata de servicios costosos.
Los providers son el mecanismo detrás de cómo Angular maneja la creación y gestión de dependencias, proporcionando un control preciso sobre cuándo y cómo se crean los servicios. Desde configuraciones básicas hasta estrategias avanzadas con useFactory
o InjectionTokens
, dominar los providers te permitirá construir aplicaciones más robustas y escalables.
I am particularly drawn to developing applications that are not only functional but also visually appealing and easy to use. I accomplish this by implementing SOLID principles and clean architecture, and applying testing to ensure quality.