Lesson 6 / 34
Dependency Injection
Understand Nest's IoC container, constructor injection and provider scopes so you never instantiate services by hand.
Inject via constructor
NestJS automatically instantiates and injects services via the constructor. No manual new needed.
@Injectable()
export class UsersService {
// service logic
}
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
}Lazy loading & scopes
By default, services are singletons (one instance for the app). You can also use REQUEST or TRANSIENT scopes for per-request or per-use instances.
Constructor injection in action
Nest reads the constructor parameter types and passes the matching provider.
@Injectable()marks the class as a provider.private readonly users: UsersServiceboth declares and stores the dependency.- You never write
new UsersService()yourself.
import { Controller, Get, Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
findAll() {
return ['asha', 'ravi'];
}
}
@Controller('users')
export class UsersController {
constructor(private readonly users: UsersService) {}
@Get()
list() {
return this.users.findAll();
}
}Why DI makes tests easy
Because the controller receives its service instead of creating it, a test can hand it a fake service. No database is needed to test the controller.
Quick check
Quick check: A provider is listed in `providers` but you inject it in another module and get an error. What is missing?
- It must be exported by its module and that module imported
- The class needs `@Controller()`
- Nest only injects providers named `Service`
Answer
It must be exported by its module and that module imported — Providers are private to their module until exported, and the consumer must import that module.