我正在尝试根据我的ConfigService
的值提供其他服务。
我遇到的问题是,在执行诸如findOne()
(结果为null
)或countDocuments()
(结果)之类的查询方法时,注入的猫鼬模型不返回任何值。是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
。
答案 0 :(得分:-1)
您可以使用工厂方法解决此问题,请尝试以下操作:
确定服务“形状”的界面:
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
],
}
];