title: Use request-specific context inside a global (singleton) service
body: <p>I'd like to be able to log (as in <code>console.log</code>) the logged-in user for every SQL query being done. I'm using Nest.js and TypeORM (and it's wrapper for Nest.js). I couldn't figure out how to inject request-specific data into a global (singleton) provider.</p>
  
  <p>I'm using Nest.js v6.6.3, and <code>@nestjs/typeorm</code> v6.1.3.</p>
  
  <pre class="lang-js prettyprint-override"><code>// current-user.service.ts
  @Injectable({ scope: Scope.REQUEST })
  export class CurrentUserService {
    get currentUser(): string | null {
      if (!this.request || !this.request.user) {
        return null;
      }
  
      return this.request.user.email;
    }
  
    constructor(@Optional() @Inject(REQUEST) private request: Request) {}
  }
  
  // logger.service.ts
  @Injectable()
  export class LoggerService extends Logger {
    constructor(private readonly moduleRef: ModuleRef) {
      super();
    }
  
    log(message: any, context?: string) {
      super.log(this.formatMessage(message), context);
    }
  
    private formatMessage(message: any) {
      // ** This is the problematic code **
      const currentUserService = this.moduleRef.get(CurrentUserService, {
        strict: false,
      });
      return `[${currentUserService.currentUser}]: ${message}`;
    }
  }
  
  // typeorm-logger.service.ts
  @Injectable()
  export class TypeormLogger implements Logger {
    // Logger is imported from `typeorm`
    constructor(private logger: LoggerService) {}
  
    logQuery(query: string) {
      // there are more params, don't matter for the sake of the argument
      this.logger.log(query);
    }
  }
  
  // logger.module.ts
  @Module({
    providers: [LoggerService, TypeormLogger],
    exports: [LoggerService, TypeormLogger],
  })
  export class LoggerModule {}
  
  // app.module.ts
  @Module({
    imports: [
      TypeOrmModule.ForRootAsync({
        imports: [LoggerModule],
        inject: [TypeormLogger],
        useFactory: (typeormLogger: TypeormLogger) =&gt; {
          return {
            type: 'mysql',
            logger: typeormLogger,
            keepConnectionAlive: false,
            ...
          };
        },
      }),
    ],
  })
  export class AppModule {}
  </code></pre>
  
  <p>It seems like using <code>moduleRef.get()</code> can't do cross-<code>Module</code> resolving, so I tried using <code>moduleRef.resolve()</code> instead, but then I still get <code>CurrentUserService</code> with a <code>request === undefined</code>. Furthermore, <code>resolve()</code> returns a <code>Promise</code>, which is not-ideal for a something like logging.</p>
  
  <p>The above is a specific use-case, but can be generalized - if you have code that's not called directly from a Controller, you can't inject transient data like the authenticated user, or a request id (both useful for logging). This seems weird, especially since Nest.js relies heavily on IoC.</p>