Dynamic modules cho phép configure module lúc runtime với tham số — khác static modules cấu hình cứng trong code.
forRoot(options) là synchronous factory nhận options và trả về DynamicModule. forRootAsync(options) hỗ trợ async config như đọc từ ConfigService:
// Cách implement forRootAsync trong custom module
static forRootAsync(options: AsyncOptions): DynamicModule {
return {
module: DatabaseModule,
imports: options.imports || [],
providers: [
{
provide: DATABASE_OPTIONS,
useFactory: options.useFactory,
inject: options.inject || [],
},
DatabaseService,
],
exports: [DatabaseService],
};
}Dùng trong AppModule:
DatabaseModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
url: config.get('DATABASE_URL'),
}),
inject: [ConfigService],
})Pattern này dùng trong TypeOrmModule.forRootAsync(), JwtModule.registerAsync(), CacheModule.registerAsync().
Dynamic modules allow runtime configuration — unlike static modules with hardcoded config.
forRoot(options) is a synchronous factory returning a DynamicModule. forRootAsync(options) supports async config like reading from ConfigService:
static forRootAsync(options: AsyncOptions): DynamicModule {
return {
module: DatabaseModule,
imports: options.imports || [],
providers: [
{ provide: DATABASE_OPTIONS, useFactory: options.useFactory, inject: options.inject || [] },
DatabaseService,
],
exports: [DatabaseService],
};
}Used in TypeOrmModule.forRootAsync(), JwtModule.registerAsync(), CacheModule.registerAsync().