Skip to content

动态模块

我们有的时候希望引入模块的时候 给模块传递参数,这个时候就需要动态模块了

快速 入门

  • 新建bbb.module.ts
ts
import { DynamicModule, Module } from "@nestjs/common";
import { BbbService } from "./bbb.service";
import { BBBController } from "./bbb.controller";

export interface ConfigOptions {
  name: string;
}

@Module({})
export class BbbModule {
  static register(options: ConfigOptions): DynamicModule {
    return {
      module: BbbModule,
      controllers: [BBBController],
      providers: [
        {
          provide: "CONFIG_OPTIONS",
          useValue: options,
        },
        BbbService,
      ],
      exports: [],
    };
  }
}
  • 注册 bbs.module.ts 模块(重点)
ts
import { BbbModule } from "./bbb/bbb.module";
import { Module } from "@nestjs/common";
// 通过注册方法引入
@Module({
  imports: [BbbModule.register({ name: "李四" })],
  controllers: [],
  providers: [],
})
export class AppModule {}
  • 使用通过@Inject(xxxx)

这里的 xxxx 必须 对应上 bbb.module.ts 中的 provide 的值

ts
import { Injectable, Inject } from "@nestjs/common";
import { ConfigOptions } from "./bbb.module";
@Injectable()
export class BbbService {
  @Inject("CONFIG_OPTIONS")
  private readonly options: ConfigOptions;

  getHello(): string {
    return this.options.name;
  }
}

方法介绍

bbb.module.ts里面的register方法其实叫什么都行

但是 nest 约定了 3 种方法名

  • register

  • forRoot

  • forFeature

register(传参)

用一次模块传一次配置,比如这次调用是 BbbModule.register({aaa:1}),下一次就是 BbbModule.register({aaa:2})

forRoot(根模块)

配置一次模块用多次,比如 XxxModule.forRoot({}) 一次,之后就一直用这个 Module,一般在 AppModuleimport

forFeature(模块)

用了 forRoot 固定了整体模块,用于局部的时候,可能需要再传一些配置,比如用 forRoot 指定了数据库链接信息,再用 forFeature 指定某个模块访问哪个数据库和表。

举例

比如 @nestjs/typeorm 模块,就是用的 forRoot 和 forFeature

forRoot 传入配置,动态产生 provider 和 exports,返回模块定义。 而且还有 forRootAsync,异步获取配置,比如从数据库获取。

区别就是可以用 async 的 useFactory 动态产生 provider,比如异步请求别的服务拿到配置返回,作为 options。

forFeature 则是传入局部的一些配置,来动态产生局部用的模块:

typeorm 的模块用起来是这样的:

  • forFeature