NestJS:依赖项注入和提供者注册 [英] NestJS: Dependency Injection and Provider Registration
问题描述
有没有人能帮我理解DI Nest的基本原理,我的问题是:
";是否可以有一个没有@Injectable Annottion的服务类,而且这个类不属于任何模块?";我在网上看到过如下示例:
此类存在于公用文件夹中:
export class NotificationService {
constructor(
@Inject(Logger) private readonly logger: LoggerService,
private readonly appConfigService: AppConfigService,
@Inject(HttpService) private readonly httpService: HttpService
) {}
async sendNotification(msg: string) {
....
}
}
然后在提供程序数组的另一个模块中注册:
import { Module, Logger, forwardRef, HttpModule } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { NotificationService } from '../../commons/notification/notification.service';
@Module({
imports: [
...
],
controllers: [InvoiceController],
providers: [
InvoiceService,
NotificationService,
Logger],
exports: [InvoiceService]
})
export class InvoiceModule { }
然后将其注入到其他服务的构造函数方法中
@Injectable()
export class InvoiceService {
constructor(
@Inject(Logger) private readonly logger: LoggerService,
private readonly notificationService: NotificationService) { }
...
}
这个工作得很好,但我不知道为什么。为什么在不使用add@injectable和不使用and import模块的情况下正确注入通知服务?
推荐答案
所以让我们详细分析一下@Injectable()
装饰符的实际情况。
@Injectable()
的情况下,我们实际上不会执行这两种操作。当然我们是setting the scope metadata,但是这似乎并没有真正设置任何关于";的元数据。嘿,这个类是可以通过Nest框架";注入的。这是因为@Injectable()
真正设置我们的是tsconfig
和tsc
编译器的一个特殊属性,即emitDecoratorMetadata
属性。有了这个属性,TypeScript将在文件的开头和结尾处添加一组额外的函数。这些函数通常如下所示
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
和
DelegatorService = __decorate([
common_1.Injectable(),
__metadata("design:paramtypes", [http_interceptor_service_1.HttpInterceptorService,
websocket_interceptor_service_1.WebsocketInterceptorService,
rpc_interceptor_service_1.RpcInterceptorService,
gql_interceptor_service_1.GqlInterceptorService])
], DelegatorService);
这是非常重要的部分,因为这"design:paramtypes"
实际上是Nest在确定要注入的内容时读取的内容。
此元数据仅在类中的任何位置使用装饰符时才可用,并且有关于元数据的was actually an eslint-typescript discussion以及import type
如何破坏它的信息,以及真正进入杂草的a recent PR。
我提出所有这些都是为了说明,因为构造函数中有@Inject()
,所以@Injectable()
实际上是无关的,除非您要设置作用域级别的元数据,否则不是必需的。类型元数据已经发出,所以这就解释了为什么您不需要@Injectable()
(尽管我仍然认为让它提供明确的意图是个好主意)。
现在,关于注入正常工作的原因,我保证这个不会太复杂:您向InvoiceModule
‘s
providersarray. This tells Nest that any service inside of
InvoiceModulehas access to
NotificationsService`添加了NotificationsService
,这样它就可以毫无问题地注入到这里。
这篇关于NestJS:依赖项注入和提供者注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!