In NestJS, dependency injection is a powerful design pattern that allows for the management of service dependencies in a clean and modular way. By using this pattern, we can easily inject dependencies into classes (such as services, controllers, etc.), which enhances code reusability and testability.
- Providers are typically services marked with the
@Injectable()
decorator. This decorator tells NestJS that the class can be managed by the dependency injection system. - Injection Example: When a service like
ProductsService
is injected into another class, such asSeedService
, it must be decorated with@Injectable()
. This enables NestJS to automatically provide an instance ofProductsService
whenSeedService
is instantiated.
import { Injectable } from '@nestjs/common';
@Injectable()
export class ProductsService {
// Service logic...
}
@Injectable()
export class SeedService {
constructor(private productsService: ProductsService) {}
}
### What Can Be Injected
In NestJS, you can inject a variety of dependencies into the constructors of your classes, including but not limited to:
1. Services (Providers): These are classes marked with the @Injectable() decorator.
```ts
constructor(private readonly myService: MyService) {}
- Repositories: When using TypeORM or another ORM, you can inject repositories using @InjectRepository.
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
- Configuration Services: You can inject configuration services or other modules that provide application configurations.
constructor(private readonly configService: ConfigService) {}
- Manually Configured Dependencies: These are custom providers or dependencies you’ve registered manually in the application context.
constructor(@Inject('CUSTOM_TOKEN') private readonly customDependency) {}
- Global Services: NestJS allows injecting global services like loggers, which are available throughout the application.
constructor(private readonly logger: Logger) {}
• The @Injectable() decorator is crucial for classes that are meant to be managed by NestJS’s dependency injection system. When you want a class to be injected as a dependency, it must be decorated with @Injectable().
• Decoupling: It decouples the instantiation of a class from its dependencies, making the code more modular.
• Testability: By allowing mock dependencies to be injected, it makes unit testing more straightforward.
• Maintainability: It helps in managing the dependencies across large applications, ensuring that dependencies are defined in a central location.
Inyectar un provider (proveedor) en una aplicación, especialmente en un marco como NestJS, nos proporciona varios beneficios clave:
1. Desacoplamiento del Código: La inyección de dependencias permite separar la lógica de una clase de la forma en que obtiene sus dependencias. En lugar de que una clase cree directamente las instancias de sus dependencias, estas se inyectan desde fuera, lo que facilita el mantenimiento y evolución del código.
2. Reutilización y Modularidad: Al inyectar providers, se promueve la reutilización del código, ya que los servicios pueden ser utilizados en múltiples lugares de la aplicación sin necesidad de recrearlos. Esto también facilita la creación de módulos independientes que pueden ser integrados en diferentes partes de la aplicación.
3. Facilidad para Realizar Pruebas: Inyectar providers permite utilizar mocks o stubs durante las pruebas unitarias, lo que hace que las pruebas sean más aisladas y precisas. En lugar de depender de implementaciones reales, se pueden inyectar versiones simuladas para verificar el comportamiento de la lógica bajo prueba.
4. Manejo Centralizado de Dependencias: La inyección de dependencias permite que la configuración de las mismas sea gestionada de forma centralizada, mejorando la organización del código y facilitando la detección de errores o la actualización de dependencias.
5. Escalabilidad: En aplicaciones grandes, la inyección de dependencias facilita la gestión de múltiples servicios y la organización del código, lo que es crucial para la escalabilidad y el mantenimiento a largo plazo.
En resumen, inyectar un provider en una aplicación ayuda a crear un código más modular, reutilizable, fácil de mantener y probar, lo que es esencial para el desarrollo de aplicaciones robustas y escalables.