Skip to content
On this page

动态模块

Provider 是可以通过 useFactory 动态产生的

module 也可以动态

动态模块声明

typescript
import { DynamicModule, Module } from '@nestjs/common';
import { BbbService } from './bbb.service';
import { BbbController } from './bbb.controller';

@Module({})
export class BbbModule {

  static register(options: Record<string, any>): DynamicModule {
    return {
      module: BbbModule,
      controllers: [BbbController],
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        BbbService,
      ],
      exports: []
    };
  }
}

动态模块的注册使用

命名规则

这里的 register 方法其实叫啥都行,但 nest 约定了 3 种方法名:

  • register
  • forRoot
  • forFeature

我们约定它们分别用来做不同的事情:

  • register:用一次模块传一次配置,比如这次调用是 BbbModule.register({aaa:1}),下一次就是 BbbModule.register({aaa:2}) 了
  • forRoot:配置一次模块用多次,比如 XxxModule.forRoot({}) 一次,之后就一直用这个 Module,一般在 AppModule 里 import
  • forFeature:用了 forRoot 固定了整体模块,用于局部的时候,可能需要再传一些配置,比如用 forRoot 指定了数据库链接信息,再用 forFeature 指定某个模块访问哪个数据库和表。

本质

就是一个返回 module 对象的函数,好处就是 module 对象可以动态生成

另一种动态模块的声明方式

新建 ccc.module-definition.ts 文件

typescript
import { ConfigurableModuleBuilder } from "@nestjs/common";

export interface CccModuleOptions {
    aaa: number;
    bbb: string;
}

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<CccModuleOptions>(type).build();
  //type默认是register,也可以是forRoot,

然后 Module 继承它:

现在这个 CccModule 就是动态模块了

注册使用

同上,继承对象上实现了 register 和 registerAsync 方法

使用返回的 MODULE_OPTIONS_TOKEN 进行注入