mongoose - 为服务扩展类时如何处理 NestJS 依赖注入?
问题描述
我正在尝试根据我的ConfigService
.
findOne()
我遇到的问题是,在执行(result is null
) 或countDocuments()
(result is )等查询方法时,注入的 mongoose 模型不返回任何值0
。
我的服务类定义如下:
export class BaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {}
createService(option: string) {
if (option === 'OTHER') {
return new OtherService(this.catModel);
} else if (option === 'ANOTHER') {
return new AnotherService(this.catModel);
} else {
return new BaseService(this.catModel);
}
}
async findOne(id: string): Promise<Cat> {
return await this.catModel.findOne({_id: id});
}
async count(): Promise<number> {
return await this.catModel.countDocuments();
}
testClass() {
console.log('BASE SERVICE CLASS USED');
}
}
@Injectable()
export class OtherService extends BaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {
super(catModel);
}
testClass() {
console.log('OTHER SERVICE CLASS USED');
}
}
@Injectable()
export class AnotherService extends BaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {
super(catModel);
}
testClass() {
console.log('ANOTHER SERVICE CLASS USED');
}
}
这使我可以从我的提供者那里获得正确的服务(testClass()
打印预期的字符串)。我的提供者如下所示:
export const catProviders = [
{
provide: 'CatModelToken',
useFactory: (connection: Connection) => connection.model('CAT', CatSchema),
inject: ['DbConnectionToken'],
},
{
provide: 'BaseService',
useFactory: (ConfigService: ConfigService, connection: Connection) => {
const options = ConfigService.get('SERVICE_TYPE');
let model = connection.model('CAT', CatSchema);
return new BaseService(model).createService(options);
},
inject: [ConfigService, 'CatModelToken', 'DbConnectionToken'],
}
];
所以我的问题分为两部分:
- 有没有更好的方法来处理正确类的创建并避免
BaseService
为了调用的唯一目的而创建实例createService()
? - 将猫鼬模型注入新创建的服务的正确方法是什么?
我也不能使用useClass
文档中的示例,因为我需要能够注入ConfigService
.
解决方案
您可以通过使用工厂方法来解决这个问题,试试这个:
确定服务“形状”的接口:
export interface IDatabaseService {
findOne(id: string): Promise<Cat>;
count(): Promise<number>;
testClass(): void;
}
BaseService 必须实现该接口:
export class BaseService implements IDatabaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {}
async findOne(id: string): Promise<Cat> {
return await this.catModel.findOne({_id: id});
}
async count(): Promise<number> {
return await this.catModel.countDocuments();
}
testClass() {
console.log('BASE SERVICE CLASS USED');
}
}
动态服务未注入,因此它们不使用@Injectable()
装饰器:
export class OtherService extends BaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {
super(catModel);
}
testClass() {
console.log('OTHER SERVICE CLASS USED');
}
}
export class AnotherService extends BaseService {
constructor(@InjectModel('Cat') public readonly catModel: Model<Cat>) {
super(catModel);
}
testClass() {
console.log('ANOTHER SERVICE CLASS USED');
}
}
工厂类是被注入的东西:
@Injectable()
export class DatabaseServiceFactory {
constructor(@InjectModel('Cat') private readonly catModel: Model<Cat>) {}
createService(name: string) : IDatabaseService {
switch(name) {
case 'other': return new OtherService(this.catModel);
case 'another': return new AnotherService(this.catModel);
default: throw new Error(`No service has been implemented for the name "${name}"`);
}
}
}
export const catProviders = [
{
provide: 'CatModelToken',
useFactory: (connection: Connection) => connection.model('CAT', CatSchema),
inject: ['DbConnectionToken'],
},
{
provide: 'BaseService',
useFactory: (ConfigService: ConfigService, connection: Connection, dbFactory: DatabaseServiceFactory) => {
const options = ConfigService.get('SERVICE_TYPE');
let model = connection.model('CAT', CatSchema);
//return new BaseService(model).createService(options);
return dbFactory.createService(options);
},
inject: [
ConfigService,
'CatModelToken',
'DbConnectionToken',
DatabaseServiceFactory
],
}
];
推荐阅读
- javascript - 使用javascript删除url参数
- python-3.x - pySpark 问题:map/parallelize 未按预期工作
- r - 用 R 中具有相同 ID 的不同数据帧中的行中的值替换列中的 NA
- javascript - 在数组数组上运行函数 - js
- agora.io - 从 AgoraRTCSDK 生成 dSYM 时的警告
- apache-spark - 当窗口/分区使用前向填充时,将条件添加到 pyspark sql 中的 last() 函数
- python - matplotlib Gridspec 子图出乎意料的不同大小
- tensorflow - 在 TPU 上训练 ELMO 以从自定义数据集生成嵌入
- python - UnimplementedError:不支持将字符串转换为浮点数
- javascript - 将 JS 库导入 Vue.js