
问一下各位大佬 我如果想以以下的方式去使用 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 a href="/member/ilaipi" class="dark">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 @NorthA #5 在 forRootAsync 这个方法调用的时候,需要传一个 factory 的方法,这个方法里你就可以传参数了。变化形式有很多,得自己思考思考 |
10 没太理解你的意思,不过看你需求,直接在类里面 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 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) } 这样 又或者是直接导入 nw 了传参也是可行 |
17 kobememory 2023-08-07 15:43:37 +08:00 |
18 kobememory 2023-08-07 15:51:18 +08:00 |
19 kobememory 2023-08-07 15:53:05 +08:00 https://imgur.com/a/fntkmtP 图片发不出来?? |
20 NorthA OP @kobememory 没错没错,就是这种差不多 |