Chicky
Chicky

Reputation: 1257

What is Injectable in NestJS?

I am studying NestJS, here is my simple service:

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

const userMock = [{ account: 'dung', password: '12345678' }];

@Injectable()
export class UserService {
  getUser() {
    return userMock
  }
}

I not really understand @Injectable in NestJS. Some tutorial tell @Injectable tell the @Controller know it's an install and can use it as a Dependency Injection. But when I remove it, it's still working.

Please give an example about difference between @Injectable and without @Injectable

Upvotes: 17

Views: 21256

Answers (3)

ninezero90hy
ninezero90hy

Reputation: 142

@Injectable() annotation allows you to inject instances.

Of course, that instance should have an @Injectible() annotation.

Let me show you an example.

@Injectable()
export class PersonService {
  getName() {
    return 'ninezero90hy';
  }
}
@Injectable()
export class AppService {
  constructor(private readonly personService: PersonService) {
    Logger.log(this.personService.getName())
  }
}

print 'ninezero90hy'

--

If there is no AppService or PersonService @Injectible() annotation, an error occurs.

--

Using the @Injectible() annotation

You can define the injection range.

This means that the nestjs container creates an instance.

--

Reference:

export declare enum Scope {
    /**
     * The provider can be shared across multiple classes. The provider lifetime
     * is strictly tied to the application lifecycle. Once the application has
     * bootstrapped, all providers have been instantiated.
     */
    DEFAULT = 0,
    /**
     * A new private instance of the provider is instantiated for every use
     */
    TRANSIENT = 1,
    /**
     * A new instance is instantiated for each request processing pipeline
     */
    REQUEST = 2
}

If you don't use @Injectible() annotations, nestjs doesn't manage instances, so an error will occur in the DI process.

Upvotes: 10

Yilmaz
Yilmaz

Reputation: 49729

With Nest.js' injector system, you can manage your objects without thinking about the instantiation of them, because that is already managed by the injector, which is there to resolve the dependencies of every dependent object. With dependency injection, we connect different classes inside a module.

Let's say you have User Service:

export class UserService() {
 private users: Array<User> = [{
    id: 1,
    email: '[email protected]',
    password: 'kjkjkj'
 ]};
 findOne(id:number): Promise<User> { 
    // should be `return this.repo.findOne(id)` but I dont wanna get into repository
 return  "write logic to return user"
 }
}

then let's say we have Authentication Service:

export class AuthenticationService {
   public userService: UserService;
   constructor() {
       this.userService = new UserService();
   }
 async validateAUser(payload: { email: string; password: string }):
     // Write logic
}

As you see, you have to manage all of the related dependencies in the class itself to be used inside the AuthenticationService. The disadvantage of this is mostly the inflexibility of the AuthenticationService.If you want to test this service, you have to think about its own hidden dependencies, and of course, you can’t share any services between different classes.

Let's say you want to add another dependency into Authentication service or maybe you want to inject a different service. Then you need to create another instance of AuthenticationService. But using dependecy we can change the dependencies at run time rather than compile time because dependencies can be injected at run time

Upvotes: 4

Jay McDoniel
Jay McDoniel

Reputation: 70600

@Injectable() is how you tell Nest this is a class that can have dependencies that should be instantiated by Nest and its DI system. The code you posted works because there are no injected dependencies. If, instead, you had

const userMock = [{ account: 'dung', password: '12345678' }];

export class UserService {
  constructor(private readonly otherService: OtherService) {}
  getUser() {
    return userMock
  }
}

OtherService would come back undefined due to UserService not being @Injectable()

Upvotes: 33

Related Questions