【问题标题】:How to inject service into imported service Nestjs如何将服务注入到导入的服务 Nestjs
【发布时间】:2018-11-16 21:09:05
【问题描述】:

我有自定义模块AuthModuleAuthServiceAuthController 和路由等等,它们工作正常,并且想在几个项目之间共享这个模块作为一个包。问题是如何扩展从这个包中导入的AuthService 以及如何在其中注入额外的服务?

更多详情

在我想要放入包中的自定义AuthService 中,注入了UserService 类,默认情况下从数据库中获取一些User 数据并将其返回到客户端。我需要注入AuthService 另一个,例如来自应用程序的ProfileService,它从数据库User 额外数据中获取。目的是合并User主数据和User额外数据,并将这组数据返回给客户端

【问题讨论】:

  • 更多上下文。也许,部分代码。什么类型的 Auth:JWT 还是 Bearer?
  • 忘了说明 AuthModule 是自定义的,在这种情况下类型无关紧要,因为它是抽象的。主要问题是如何将一些应用程序服务注入到从包中导入的另一个服务中

标签: nestjs


【解决方案1】:

我认为这里不需要动态模块。

确实,只需要从您的 AuthModule 中导出您要注入到由 NestJs 管理的其他实体的服务,并在您希望其他实体注入您的 AuthService 的模块中导入 AuthModule。

import { Module } from '@nestjs/common'
import { AuthService } from './AuthService'

@Module({
  providers: [
    AuthService,
    // ... others
  ],
  exports: [
    AuthService
  ]
})
export class CommonModule {}

然后在您的依赖类(假设是另一个控制器,但可以是 GraphQL 解析器、拦截器或其他任何东西)中,您声明对 AuthService 的依赖。

import { AuthService } from '../auth/AuthService'
import { Dependencies } from '@nestjs/common'

@Dependencies(AuthService)
export class DependentController {
  constructor (authService) {
    this.authService = authService
  }
}

最后,为了 AuthService 对依赖的控制器可用,它必须被导入到提供控制器的同一个模块中。

import { Module } from '@nestjs/common'
import { CommonModule } from '../auth/CommonModule'
import { DependentController } from './controller/DependentController'

@Module({
  imports: [
    CommonModule,
    // ...others
  ],
  providers: [
    DependentController,
    // ...others
  ]
})
export class ControllerModule {}

我知道语法可以更短,并且在 typescript 中不使用 Dependencies 装饰器,但是问题的核心是从提供的模块中导出共享服务,然后将该模块导入模块中其他需要它的类。

【讨论】:

    【解决方案2】:

    这是为 Dynamic Modules 创建的用例之一。

    import { Module, DynamicModule } from '@nestjs/common';
    import { createDatabaseProviders } from './database.providers';
    import { Connection } from './connection.provider';
    
    @Module({
      providers: [Connection],
    })
    export class DatabaseModule {
      static forRoot(entities = [], options?): DynamicModule {
        const providers = createDatabaseProviders(options, entities);
        return {
          module: DatabaseModule,
          providers: providers,
          exports: providers,
        };
      }
    }
    

    在此示例中,查看如何将providers (动态)提供给结果模块。

    您的包应该遵循相同的模式:公开一个允许构建DynamicModule 的静态方法,这样您就可以根据需要解析其他服务(内部或外部)(构建您自己的providers 数组)。

    【讨论】:

    • 在我的情况下,我必须将所有模块包装到函数中,然后通过参数传递我的服务。像这样:` //app.js import_{createAuthModule} from 'mypackage';从 '../../modules/profile' 导入 {ProfileService} const AuthModule = createAuthModule(ProfileService); ` 但这不是一个优雅的解决方案
    • 我在考虑更接近YourModule.createDynamically(...) 的东西,但你将无法接近任何比DynamicModule 更优雅的东西。首先,您的方法可能无效。一个模块应该是自给自足的和/或嵌入它自己的依赖项。如果您想允许它是开放式的,那么您必须接受它要求您提供正确的依赖项。祝你好运,玩得开心使用 Nest!
    猜你喜欢
    • 2020-09-09
    • 1970-01-01
    • 2020-06-23
    • 2020-12-11
    • 1970-01-01
    • 2022-09-24
    • 2019-04-25
    • 1970-01-01
    • 2020-06-06
    相关资源
    最近更新 更多