#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 мы можем изменять зависимости во время выполнения, а не во время компиляции, потому что зависимости могут быть введены во время выполнения