CodePark/ questions / Providers & dependency injection
START PRACTICINGPRACTICE
Backend question · NestJS › Providers & dependency injection

How does dependency injection work in Nest? What lets Nest know what to inject into a constructor?

@Injectable()
export class CatsService {
  constructor(private readonly repo: CatsRepository) {}
}

Nest creates your classes and passes them into constructors for you. It finds the right object by its token: a key that names a provider. For a class-typed parameter, the token is the class itself.

How it works:

  • Classes marked with @Injectable(), and controllers, are registered as providers in a module.
  • At bootstrap, Nest builds a dependency graph. This is a map of which class needs which.
  • By default, Nest creates each provider once and caches it.
  • Nest passes those instances into the constructors that need them.

How does Nest know the parameter types? TypeScript writes the parameter types into metadata. It does this because emitDecoratorMetadata is enabled and the class has a decorator. Nest reads that metadata to find the matching provider.

Interfaces and type aliases disappear when TypeScript compiles, so they can't be tokens. For those, you use a string or symbol token with @Inject(TOKEN).

  • Providers are registered in modules and resolved by the IoC (inversion of control) container.
  • For a class-typed parameter, the token is the class itself.
  • Nest relies on the type metadata from emitDecoratorMetadata.
  • Providers are singletons by default: created once and cached.
  • Interfaces need a string or symbol token with @Inject().