问一下各位大佬 我如果想以以下的方式去使用 LoggerService ,并且需要传递参数,是不是只能在 module 文件里面 provide 使用 useValue 。 因为我已经把 Logger 设置成了全局模块了,感觉要是继续在 provide 使用 useValue 就感觉没做全局一样,有没有其它方式能处理这个传参,比如使用个注解之类的,有没有比较好的方法? 我就暑假这两天看了一下 nestjs 的文档,想看看上面的问题能不能就使用 nest 的一些特性去解决,有大佬给个思路也行
// user.service.ts
@Injectable()
export class UserService {
constructor(private readonly logger: LoggerService) {}
}
// user.module.ts
@Module({
controllers: [UserController],
providers: [
UserService,
{
provide: LoggerService,
useValue: new LoggerService('user'),
},
],
})
export class UserModule {}
// src/app.module.ts
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { UserModule } from './user/user.module'
import { LoggerModule } from './libs/logger/logger.module'
@Module({
imports: [UserModule, LoggerModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
// src/libs/logger/logger.module.ts
import { Global, Module } from '@nestjs/common'
import { LoggerService } from './logger.service'
@Global()
@Module({
providers: [LoggerService],
exports: [LoggerService],
})
export class LoggerModule {}
// src/libs/logger/logger.service.ts
import { ConsoleLogger, Injectable, Scope } from '@nestjs/common'
import { Signale } from 'signale'
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService extends ConsoleLogger {
private readonly logger: Signale
private readonly scope: string
constructor(scope = 'app') {
super()
this.logger = new Signale({
stream: process.stdout,
disabled: false,
interactive: false,
})
this.scope = scope
this.logger.scope(this.scope)
this.logger.config({
displayTimestamp: true, // 以 HH:MM:SS 的格式显示当前本地时间。
displayDate: true, // 以 YYYY-MM-DD 的格式显示当前本地日期。
displayFilename: false, // 显示记录器消息来源的文件名。
})
}
complete(message: string, ...args: any[]) {
this.logger.complete(message, ...args)
}
}
1
NorthA OP 总感觉要是写一个模块,就得 provide 一次,那 100 个 service 就得导入 100 次,这种比较重复性的工作感觉没必要
不传参,暴露一个方法去动态设置也行,不过我就是想知道 nestjs 有没有什么特性能解决这个问题,毕竟初学想了解一下😊 |
2
RomeoHong 2023-07-30 01:59:25 +08:00
也可以在 LoggerModule 上 providers 多个 LoggerService ,如:AppLoggerService, OtherLoggerService..., 这样可以不用使用 useValue 吧
|
3
ilaipi 2023-07-30 07:19:59 +08:00
|
4
lee88688 2023-07-30 07:30:55 +08:00 via Android
#3 楼的方法应该可以的,全局注册的 module 起导出的 service 在任何地方都可以使用,可以看看 nest 自带的一些模块例如 config ,注册方式可以全局也可以局部。
|
5
NorthA OP |
6
NorthA OP @lee88688 可能大佬没回复到我想要的点上,举个简单的例子,我有 a ,b ,c ,d 四个模块,logger 已经全局注册了,就是想 a,b,c,d 在使用 logger 的时候给构造器传递一个参数,我目前只知道在 provides 里面去引入 logger 然后使用 useValue 传参
|
8
ilaipi 2023-07-30 10:26:21 +08:00 1
@NorthA #5 在 forRootAsync 这个方法调用的时候,需要传一个 factory 的方法,这个方法里你就可以传参数了。变化形式有很多,得自己思考思考
|
10
April5 2023-07-30 12:53:26 +08:00
没太理解你的意思,不过看你需求,直接在类里面 new 一个 Logger 就好了好像。
``` import { Injectable, Logger } from '@nestjs/common'; @Injectable() export class XService implements OnModuleInit { private readonly logger = new Logger(XService.name); ``` |
11
NorthA OP @April5 想着使用一下 nestjs 的特性来完成这个事情,在类里面 new 一下这个就没用上 nestjs 的特性了
|
13
Shamiko 2023-07-30 18:32:26 +08:00 1
app.useLogger(app.get(XXLogger))
或者 Logger.overrideLogger(moduleRef.get(XXLogger)) 然后直接 new Logger(XXService.name) |
15
lee88688 2023-07-30 22:43:53 +08:00 via Android
感觉楼主更想要一个工厂函数,根据不同的参数创建,或者根据当前的 module 的情况创建。
|
16
NorthA OP @lee88688 #15 是这么个感觉了,就是 logger 已经是全局了,我只用在 service 模块的构造器中
constructor(private readonly logger: LoggerService) 主要就是那个 scope 的参数传递,想用 nestjs 的特性去实现一下,因为是初学 nest 想折腾一下 不折腾我完全可以暴露一个 setScope 方法来动态设置 比如 (目前我是这么做了)看到 ConsoleLogger 里面也是实现了一个 setContext constructor(private readonly logger: LoggerService) { this.logger.setScope(service.name) } 这样 又或者是直接导入 new 了传参也是可行 |
17
kobememory 2023-08-07 15:43:37 +08:00
|
18
kobememory 2023-08-07 15:51:18 +08:00 1
|
19
kobememory 2023-08-07 15:53:05 +08:00
https://imgur.com/a/fntkmtP
图片发不出来?? |
20
NorthA OP @kobememory 没错没错,就是这种差不多
|