intermediate
NestJS providers
Model injectable services, repositories, factories, tokens, scopes, and lifecycle hooks without hiding domain boundaries.
Providers are injectable classes (or values/factories) registered in a module's `providers` array. `@Injectable()` marks a class for DI. Services, repositories, and adapters are typical providers.
@Injectable()
export class UsersService {
constructor(private readonly repo: UsersRepository) {}
async create(dto: CreateUserDto) {
return this.repo.save(dto);
}
}
Custom providers use `useClass`, `useValue`, `useFactory`, and injection tokens for interfaces. Scope defaults to singleton per module; `Scope.REQUEST` creates one instance per HTTP request — use sparingly due to cost.
On interviews: explain provider lifetime, when factories beat classes, and how repositories hide persistence from services.
Common pitfalls: request-scoped providers everywhere, registering the same provider in multiple modules without exporting, and services that know HTTP details.
Checklist:
- Mark domain services `@Injectable()`.
- Hide persistence behind repository providers.
- Prefer singleton scope unless request context is required.
- Use tokens for interface-to-implementation binding.