Providers

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 10 min

Providers are the core concept of Dependency Injection in NestJS. Almost everything is a provider – services, repositories, factories, helpers, etc.

Overview

The main idea of a provider is that it can be injected as a dependency; this means objects can create various relationships with each other, and the function of “wiring up” instances of objects can largely be delegated to the Nest runtime system.

A provider is simply a class annotated with an @Injectable() decorator.

Key Concepts

  • @Injectable(): A decorator that attaches metadata, which declares that the class can be managed by the Nest IoC (Inversion of Control) container.
  • Registration: Providers must be registered in the providers array of a module before they can be used.
  • Injection: Providers are typically injected through constructor injection, though property-based injection is also possible.
  • Scopes: By default, providers are singletons (instantiated once per application lifecycle). They can also be scoped per-request or transient.

Code Examples

Defining a Provider

import { Injectable } from '@nestjs/common';
import { User } from './interfaces/user.interface';

@Injectable()
export class UsersService {
  private readonly users: User[] = [];

  create(user: User) {
    this.users.push(user);
  }

  findAll(): User[] {
    return this.users;
  }
}

Injecting a Provider

Here we inject the UsersService provider into a Controller.

import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  // Nest will resolve the usersService automatically!
  constructor(private usersService: UsersService) {}

  @Post()
  create(@Body() user: any) {
    this.usersService.create(user);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }
}

Best Practices

  • Design for Testability: Because providers are injected, it is very easy to mock them during Unit Testing by providing a mock class instead of the real one.
  • Single Responsibility Principle: Keep your providers focused. A UserService shouldn’t also be sending emails; that should be delegated to a MailService.