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: UsersService both 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.