Что можно вводить в NestJS?

#node.js #nestjs

#node.js #typescript #nestjs

Вопрос:

Я изучаю NestJS, вот мой простой сервис:

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

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

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

  

Я не очень разбираюсь @Injectable в NestJS. В каком @Injectable -то руководстве рассказывается @Controller , что это установка, и вы можете использовать ее как внедрение зависимостей. Но когда я удаляю его, он все еще работает.

Пожалуйста, приведите пример о разнице между @Injectable и без @Injectable

Ответ №1:

@Injectable() это то, как вы сообщаете Nest, что это класс, который может иметь зависимости, которые должны быть созданы Nest и его системой DI. Опубликованный вами код работает, потому что нет введенных зависимостей. Если вместо этого у вас было

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

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

OtherService вернется undefined из-за UserService отсутствия @Injectable()

Комментарии:

1. Как я понимаю, если у нас есть @Injectable , это говорит NestJS, что класс может использовать другую службу другого модуля. Верно?

2. Я попытался импортировать модуль, который был начальным в модуле, но при удалении @Injectable в сервисе все равно ошибка. Это означает, что если мы хотим использовать другой класс, я должен инициализировать @Injectable . Это правильно???

3. Как тогда вы объясните это: «Декоратор, который помечает класс как поставщика. Провайдеры могут быть внедрены в другие классы посредством внедрения параметров конструктора с использованием встроенной системы внедрения зависимостей (DI) Nest «.?

4. @PromiseIhunna честно говоря, это простой ответ для тех, кто не знает, как работает Typescript и отражение метаданных. Я буду работать над добавлением расширенной страницы в документы, чтобы лучше понять, что на самом деле делают декораторы.

5. @JayMcDoniel Думаю, теперь я понимаю, пожалуйста, дайте мне знать, когда это будет готово, спасибо.

Ответ №2:

@Injectable() аннотация позволяет вводить экземпляры.

Конечно, этот экземпляр должен иметь аннотацию @Injectible() .

Позвольте мне показать вам пример.

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

выведите ‘ninezero90hy’

Если нет @Injectible() аннотации AppService или PersonService, возникает ошибка.

Использование аннотации @Injectible()

Вы можете определить диапазон впрыска.

Это означает, что контейнер nestjs создает экземпляр.

Ссылка:

 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
}

  

Если вы не используете @Injectible() аннотации, nestjs не управляет экземплярами, поэтому в процессе DI возникнет ошибка.

введите описание изображения здесь

Комментарии:

1. Этот ответ неверен. PersonService не нуждается в аннотации @Injectable в примере.

2. Этот ответ неверен, @Injectable используется только в том случае, если ваш класс зависит от других поставщиков. Он используется для того, чтобы nestjs мог создавать дерево зависимостей во время выполнения

Ответ №3:

С Nest.js «система инжектора, вы можете управлять своими объектами, не думая о их создании, потому что это уже управляется инжектором, который предназначен для разрешения зависимостей каждого зависимого объекта. С помощью внедрения зависимостей мы подключаем разные классы внутри модуля.

Допустим, у вас есть пользовательский сервис:

 export class UserService() {
 private users: Array<User> = [{
    id: 1,
    email: 'user@email.com',
    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"
 }
}
  

тогда допустим, у нас есть служба аутентификации:

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

Как вы видите, вам нужно управлять всеми связанными зависимостями в самом классе
, которые будут использоваться внутри AuthenticationService. Недостатком этого является в основном негибкость службы аутентификации.Если вы хотите протестировать этот сервис, вам нужно подумать о его собственных скрытых
зависимостях, и, конечно, вы не можете делиться никакими сервисами между разными
классами.

Допустим, вы хотите добавить еще одну зависимость в службу аутентификации или, может быть, вы хотите внедрить другую службу. Затем вам нужно создать еще один экземпляр AuthenticationService. Но с помощью dependecy мы можем изменять зависимости во время выполнения, а не во время компиляции, потому что зависимости могут быть введены во время выполнения