Nest.js 没有构造函数的 Mongoose 模型依赖注入
Nest.js Model Dependency Injection with Mongoose with no constructor
我需要将 CRM API 与我在 Nest.js 中的服务集成。不幸的是,他们要求我实现他们的接口以使用自定义持久层,在我的例子中,Mongo。由于我需要实例化生成的 class,因此我无法像往常一样注入模型,因此我尝试在 class 成员变量上使用它。但是这样会导致成员变量未定义的错误。
这是我的猫鼬模型:
export type ZohoTokenDocument = ZohoToken & Document;
@Schema({ timestamps: true })
export class ZohoToken {
@Prop()
name: string;
@Prop({ type: String, length: 255, unique: true })
user_mail: string;
@Prop({ type: String, length: 255, unique: true })
client_id: string;
@Prop({ type: String, length: 255 })
refresh_token: string;
@Prop({ type: String, length: 255 })
access_token: string;
@Prop({ type: String, length: 255 })
grant_token: string;
@Prop({ type: String, length: 20 })
expiry_time: string;
}
export const ZohoTokenSchema = SchemaFactory.createForClass(ZohoToken);
这是我根据第 3 方的要求创建的自定义 class API:
export class ZohoStore implements TokenStore {
@InjectModel(ZohoToken.name)
private readonly tokenModel: Model<ZohoTokenDocument>;
async getToken(user, token): Promise<any> {
const result = await this.tokenModel.findOne({ grant_token: token });
return result;
}
...
在我的服务中,我只是将此 class 实例化为 new ZohoStore()
,在稍后调用 getToken()
方法之前它工作正常。
产生的错误是:"nullTypeError: Cannot read property 'findOne' of undefined",
,这对我来说意味着 tokenModel
没有被实例化。知道如何将我的模型注入此 class 而无需将其放入构造函数中,否则我无法使用服务中的零参数构造函数实例化它吗?
如果您尝试使用 Nest DI 系统,那么您不能自己调用 new ZohoStore()
,因为 Nest 没有机会实例化 ZohoStore
的依赖项。
您需要将其注册为某个 NestJS 模块中的提供程序,然后如果需要,可以检索由 NestJS 创建的实例 。
为了添加到@Micael 的回复中,您需要执行以下操作:
- 将商店添加到将使用 DI 的模块:
@Module({
imports: [MongooseModule.forFeature([{ name: ZohoToken.name, schema: ZohoTokenSchema }])],
exports: [ZohoStore, ZohoService],
providers: [ZohoStore, ZohoService],
controllers: [ZohoController]
})
export class ZohoModule {}
- 务必将
@Injectable()
装饰器添加到 Store class 并使用 DI 注入模型:
@Injectable()
export class ZohoStore implements TokenStore {
constructor(@InjectModel(ZohoToken.name)
private readonly tokenModel: Model<ZohoTokenDocument>){};
- 在服务 class 中,如下引用
ZohoStore
所以当您准备好使用它时,您只需从 class 成员变量中调用 this.zohoStore
而不是尝试用 new
: 实例化它
@Injectable()
export class ZohoService {
private zohoStore: ZohoStore;
constructor(private moduleRef: ModuleRef) {}
onModuleInit() {
this.zohoStore = this.moduleRef.get(ZohoStore);
}
我需要将 CRM API 与我在 Nest.js 中的服务集成。不幸的是,他们要求我实现他们的接口以使用自定义持久层,在我的例子中,Mongo。由于我需要实例化生成的 class,因此我无法像往常一样注入模型,因此我尝试在 class 成员变量上使用它。但是这样会导致成员变量未定义的错误。
这是我的猫鼬模型:
export type ZohoTokenDocument = ZohoToken & Document;
@Schema({ timestamps: true })
export class ZohoToken {
@Prop()
name: string;
@Prop({ type: String, length: 255, unique: true })
user_mail: string;
@Prop({ type: String, length: 255, unique: true })
client_id: string;
@Prop({ type: String, length: 255 })
refresh_token: string;
@Prop({ type: String, length: 255 })
access_token: string;
@Prop({ type: String, length: 255 })
grant_token: string;
@Prop({ type: String, length: 20 })
expiry_time: string;
}
export const ZohoTokenSchema = SchemaFactory.createForClass(ZohoToken);
这是我根据第 3 方的要求创建的自定义 class API:
export class ZohoStore implements TokenStore {
@InjectModel(ZohoToken.name)
private readonly tokenModel: Model<ZohoTokenDocument>;
async getToken(user, token): Promise<any> {
const result = await this.tokenModel.findOne({ grant_token: token });
return result;
}
...
在我的服务中,我只是将此 class 实例化为 new ZohoStore()
,在稍后调用 getToken()
方法之前它工作正常。
产生的错误是:"nullTypeError: Cannot read property 'findOne' of undefined",
,这对我来说意味着 tokenModel
没有被实例化。知道如何将我的模型注入此 class 而无需将其放入构造函数中,否则我无法使用服务中的零参数构造函数实例化它吗?
如果您尝试使用 Nest DI 系统,那么您不能自己调用 new ZohoStore()
,因为 Nest 没有机会实例化 ZohoStore
的依赖项。
您需要将其注册为某个 NestJS 模块中的提供程序,然后如果需要,可以检索由 NestJS 创建的实例 。
为了添加到@Micael 的回复中,您需要执行以下操作:
- 将商店添加到将使用 DI 的模块:
@Module({
imports: [MongooseModule.forFeature([{ name: ZohoToken.name, schema: ZohoTokenSchema }])],
exports: [ZohoStore, ZohoService],
providers: [ZohoStore, ZohoService],
controllers: [ZohoController]
})
export class ZohoModule {}
- 务必将
@Injectable()
装饰器添加到 Store class 并使用 DI 注入模型:
@Injectable()
export class ZohoStore implements TokenStore {
constructor(@InjectModel(ZohoToken.name)
private readonly tokenModel: Model<ZohoTokenDocument>){};
- 在服务 class 中,如下引用
ZohoStore
所以当您准备好使用它时,您只需从 class 成员变量中调用this.zohoStore
而不是尝试用new
: 实例化它
@Injectable()
export class ZohoService {
private zohoStore: ZohoStore;
constructor(private moduleRef: ModuleRef) {}
onModuleInit() {
this.zohoStore = this.moduleRef.get(ZohoStore);
}