node.js - NestJS - 如何使用不同的配置多次注册动态模块提供程序?
问题描述
我有一个 knex 模块,它是这样实现的:
import { DynamicModule, Module } from '@nestjs/common';
import { Knex, knex } from 'knex';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
export const KNEX_MODULE = 'KNEX_MODULE';
@Module({})
export class KnexModule {
static register(options: Knex.Config): DynamicModule {
return {
module: KnexModule,
providers: [
{
inject: [WINSTON_MODULE_PROVIDER],
provide: KNEX_MODULE,
useFactory: (logger: Logger) => {
logger.info('Creating new knex instance', {
context: KnexModule.name,
tags: ['instance', 'knex', 'create'],
});
return knex(options);
},
},
],
exports: [KNEX_MODULE],
};
}
}
我的应用程序需要访问多个数据库,我知道我可以通过创建多个 knex 实例来做到这一点。所以我尝试两次注册模块,传递不同的配置。但是,该模块只注册了一次。第二个注册调用似乎是重用现有对象而不是创建一个新的 knex 实例。
根据传递的配置,生成多个提供程序的正确方法是什么?我发现最接近的是 typeORM 和 Sequelize 中的 forFeature 函数
解决方案
我刚刚找到了解决方案。我想错了。我需要在我的模块中注册两个提供程序。不创建我的模块的两个实例。我通过向我的模块添加一个参数来解决它,即提供者令牌。现在它正确地创建了两个提供者。
import { DynamicModule, Module } from '@nestjs/common';
import { Knex, knex } from 'knex';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
export const KNEX_MODULE = 'KNEX_MODULE';
@Module({})
export class KnexModule {
static register(token: string, options: Knex.Config): DynamicModule {
return {
module: KnexModule,
providers: [
{
inject: [WINSTON_MODULE_PROVIDER],
provide: token,
useFactory: (logger: Logger) => {
logger.info('Creating new knex instance', {
context: KnexModule.name,
tags: ['instance', 'knex', 'create'],
});
return knex(options);
},
},
],
exports: [token],
};
}
}
每当我想使用它时,我都会像这样注册它:
@Module({
imports: [KnexModule.register(CatRepository.KNEX_TOKEN, knexConfigs)],
providers: [CatRepository, CatService],
controllers: [CatController],
exports: [CatService],
})
export class CatModule {}
然后在存储库中,我可以注入 cat 数据库的 knex 实例。
@Injectable()
export class CatRepository implements Repository<Cat> {
// eslint-disable-next-line no-useless-constructor
public static KNEX_TOKEN = 'KNEX_CATS_TOKEN';
// eslint-disable-next-line no-useless-constructor
constructor(
@Inject(CatRepository.KNEX_TOKEN)
protected knex: Knex,
) {}
...
}