NestJS Dependency Injection - Overview
Tags: javascript, webdev, nestjs, node
Published: 2024-01-29 11:25:49

## Video Explanation

Please find video explanation below:

{% youtube ZCbGVoqAEX0 %}

## Introduction

Lets first divide the entire term in two parts. "Dependency" and "Injection". 
This suggests that there could be one dependency class which needs to be "injected" to another class (simplest of the example).

In nest.js, we normally inject providers (services) in controllers to perform some sort of business logic.

Please note that the task of service should not be authentication, authorization, validation, transformation and/or extending or overriding the function. Because, for all this, we have separate components in nest.js like middleware, guards, pipes and interceptors.

Make sure that the dependency you make should have one concern and the concern should be specific to the business logic you plan to implement.

## Non Dependency Example

Lets take a look at the example below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9obwbtaqmozew6o8i83c.png)

**Car** has an **Engine** that means, **Car depends upon Engine**.
As such, we have two classes, i.e., Car and Engine.

If you notice here:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfy6qciplprlsvjtofru.png)

We are directly instantiating Engine in the Car. You must have done this in other programming languages as well. This means that **Car and Engine are tightly coupled**. If you were to make any changes in Engine, then you might have to make changes in your class code as well to make sure that the Car class instantiates the Engine class correctly.

In short, in this example, **your code is managing the dependency**.

## Goal of Dependency Injection
The main goal that dependency injection achieves is to reverse the order of things explained earlier.

Instead of the code managing the dependency, it ensures that the dependencies and their relationships are **managed by library or framework**. In our case, the dependencies would be managed by Nest.js runtime system.

## Creating Injectable Dependency

Nest.js allows `@Injectable()` decorator to perform this operation. It can be imported from `@nestjs/common`. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftk1u6rq7m291ik393fm.png)

This decorator needs to be placed right above the class and it ensures to add metadata to the class which makes the class as injectable to other classes via. dependency injection.

Make sure that the class you tend to make as a dependency is exported as shown in above image.

Some basic code would be like this:

```js
import { Injectable } from '@nestjs/common';

@Injectable()
export class ShameelService {}
```

Now lets take a look at the following code:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esexj9g69158o0hupnfm.png)

What I have done above is created a private variable `cats` which is an array of strings and created two methods `create()` which pushes incoming argument to `cats` variable and `findaAll()` which simply returns the `cats` array. It's pretty simple, no rocket science intended.

## Injecting Service in Controller

This is the simplest code to inject service in a controller:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tpm882lztuwmgrvwzpe.png)

This is an example of dependency injection via. constructor (you guessed it right, there are other method but we will only be covering constructor based dependency injection here).

Lets understand that line a bit which does all the magic..

```js
constructor(private readonly catService:CatService)
```

So, we have a variable named `catService` which is `private` and `readonly`. This means, the scope of this variable is within this file only and it cannot be modified by any means from this file during run time.

The magical part is `CatService` which in TypeScript defines the type of `catsService` variable.

Lets add the following code here:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzmarr7skhau9outclv3.png)

The code implements POST endpoint which adds incoming arguments to the `cats` privatevariable in `CatsService`.

But... How does `CatsController` just got access to everything within `CatsService`? Because, as far as the programming concept goes, `CatsService` needs to be fully resolved and its instance must be created so that it can be utilized somewhere else. Lets discuss this below.

## Registering the Dependency

The key part after creating a dependency is to **register** it. Once you register the dependency then whenever you run your nest.js application, it will first resolve the dependency and create its instance.

Nest.js keeps instances of the providers within an IoC (Inversion of Control) container. Whenever some control tends to perform dependency injection for some service, nest.js runtime picks that service from its container and provides it to that particular controller, provided that the controller is in the scope of the service it tends to inject.

If you do not register your service and tends to inject it then you will get the following error:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hegio9l6h0h5475mu8p.png)

Nest.js suggests you the following suggestions:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbqwsoew5id05hjzybxe.png)

In order to register your service within a module, all you have to do is to give provider class name in `providers` array within the `module`.

```js
@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

## Conclusion

Provider and Controller both are classes. The difference comes from the decorator being used at the top of the class which adds relevant metadata to that particular class.

These are the steps that you have to follow:

1. Create a dependency with `@Injectable()` decorator.
2. Register the dependency within the module.
3. Apply dependency injection within the Controller to get access to the instance of the dependency.

In next article, we will understand what actually is Inversion of Control, that we slightly mentioned in our article here.

Happy coding! 🚀

**Follow me for more such content**:
YouTube: https://www.youtube.com/@ShameelUddin123
LinkedIn: https://www.linkedin.com/in/shameeluddin/
GitHub: https://github.com/Shameel123