Dependency Injection is a design pattern that allows a class to receive its dependencies from external sources rather than creating them itself. This promotes loose coupling, enhances testability, and makes your code more maintainable. With DI, your classes are not responsible for instantiating their dependencies, leading to cleaner and more organized code structures.
NestJS is built with TypeScript and designed around the concepts of modularity and DI. It uses decorators and modules to handle the creation and lifecycles of objects. Let’s break down how you can leverage DI in NestJS.
Let’s start by creating a simple service class that we will inject into our controller.
import { Injectable } from '@nestjs/common'; @Injectable() export class UsersService { private readonly users = []; createUser(name: string) { this.users.push(name); return this.users; } getUsers() { return this.users; } }
In this example, we have a UsersService
that manages a list of users. The @Injectable()
decorator marks the class as a potential provider that can be injected into other classes.
Next, we need to register our UsersService
with a module so that it can be injected into other classes like controllers.
import { Module } from '@nestjs/common'; import { UsersService } from './users.service'; import { UsersController } from './users.controller'; @Module({ providers: [UsersService], controllers: [UsersController], }) export class UsersModule {}
The @Module()
decorator creates a module and takes an object with providers
and controllers
. This configuration allows NestJS to recognize UsersService
as a service that can be injected into UsersController
.
Now that we have our service registered, we can inject it into a controller.
import { Controller, Post, Body, Get } from '@nestjs/common'; import { UsersService } from './users.service'; @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Post() createUser(@Body('name') name: string) { return this.usersService.createUser(name); } @Get() getUsers() { return this.usersService.getUsers(); } }
In the UsersController
, we inject the UsersService
through the constructor. By using the private
keyword in the constructor parameter, NestJS automatically creates a private instance variable usersService
that we can use throughout the class.
NestJS allows you to use various types of providers, such as constants, classes, and factories. Let's see how to use a factory provider as an example.
const databaseProvider = { provide: 'DATABASE_CONNECTION', useFactory: () => { // Normally you'd create a DB connection here return 'Database connection established'; }, }; @Module({ providers: [databaseProvider], }) export class AppModule {}
In this example, we’ve registered a provider using useFactory
, which allows us to execute a function or logic to create a value when it’s needed.
We can now inject this provider into a service or controller as follows:
import { Inject, Injectable } from '@nestjs/common'; @Injectable() export class AppService { constructor(@Inject('DATABASE_CONNECTION') private dbConnection: string) {} getDatabaseConnection() { return this.dbConnection; } }
By using the @Inject()
decorator, we can specify the provider we want NestJS to inject, allowing us to access the database connection string stored in our provider.
With NestJS, Dependency Injection provides an elegant way to manage your application's services and improve code maintainability and testability. By understanding how to create services, register them within modules, and inject them into controllers or other services, you can leverage the full power of this design pattern in your applications.
Using DI not only helps your code structure but also aligns with best practices in software development, enabling you to build robust, flexible applications. Now, it’s time to dive deeper into creating more advanced services and explore other features that NestJS provides for backend development!
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS
10/12/2024 | NestJS