Nest动态模块

128 阅读2分钟

在缕一缕 Nest 中@Module的各个功能块的作用:

@Module({
  imports: [
    RequestModule,
    TheDynamicModule.register({
      name: '彭尼玛',
    }),
  ],
  controllers: [AppController, HostController],
  providers: [AppService, ConsoleLogger, MyLogger],
})

Providers

许多基础的 Nest 类都可以被视为 provide ,比如上面用到的 service(实现业务逻辑)repository(实现数据库的 CRUD) 等,实际上只需要给一个类添加一个 @Injectable() 装饰器,那么这个类就会是一个 提供者

提供者可以通过 controllers 里的 Controller 类的 constructor(构造器函数) 注入依赖关系

Controller 类的职责:接收 http 请求,然后调用 service 返回响应。

有些时候,你会希望能从外面传一些选项提供者,这时候就需要用到 useValue

@Modules({
  controllers: [TheDynamicController],
  providers: [
    {
      provide: 'CONFIG_OPTIONS',
      useValue: {
        name: 'PNM',
      },
    },
  ],
})

通过上面的方式,我们创建了一个可以自定义配置对象的提供者。然后我们就可以在 TheDynamicController 中通过 @Inject('CONFIG_OPTIONS') 注入。

// TheDynamicController.ts
export class TheDynamicController {
  constructor(
    private readonly theDynamicService: TheDynamicService,
    @Inject('CONFIG_OPTIONS') private configOptions: Record<string, any>
  ) {}
}

上面举的例子被称为 值提供者(useValue),其他还有 工厂提供者(useFactory),类提供者(useClass)等

动态模块

imports 中存入的就是各个模块,除了普通模块外,我们还可以根据不同的配置生成动态模块Nest 中为我们规范了一些静态方法去创建,比如:

register 静态方法
// 创建
@Module({})
export class TheDynamicModule {
  static register(options: Record<string, any>): DynamicModule {
    return {
      module: TheDynamicModule,
      controllers: [TheDynamicController],
      // 实际上也是给提供者一个 动态值,在 control 里调用这个提供者
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        TheDynamicService,
      ],
    }
  }
}

// 使用
@Module({
  imports: [
    TheDynamicModule.register({
      name: '彭尼玛',
    }),
  ],
})
export class AppModule implements NestModule {}

register 只是其中一种,Nest 共约定了三种静态方法名:

  • register:用一次模块传一次配置

  • forRoot:配置一次,模块用多次,一般在 AppModule 里,且还有 forRootAsync 可以整一些异步的操作

  • forFeature:用了 forRoot 之后,用 forFeature 传入局部配置,一般在具体模块里 imports