Nest.js 模型依赖注入与 Mongoose 没有构造函数

Posted

技术标签:

【中文标题】Nest.js 模型依赖注入与 Mongoose 没有构造函数【英文标题】:Nest.js Model Dependency Injection with Mongoose with no constructor 【发布时间】:2022-01-21 14:53:02 【问题描述】:

我需要在 Nest.js 中将 CRM API 与我的服务集成。不幸的是,他们要求我实现他们的接口以使用自定义持久层,在我的例子中是 Mongo。因为我需要实例化生成的类,所以我不能像往常一样注入模型,所以我尝试在类成员变量上使用它。但是,这会导致成员变量未定义的错误。

这是我的猫鼬模型:

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 方 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;
  
...

在我的服务中,我只是将这个类实例化为new ZohoStore(),在稍后调用getToken() 方法之前它工作正常。

产生的错误是:"nullTypeError: Cannot read property 'findOne' of undefined",,这对我来说意味着tokenModel 没有被实例化。知道如何将模型注入此类而不将其放入构造函数中,否则我无法使用服务中的零参数构造函数对其进行实例化?

【问题讨论】:

【参考方案1】:

如果您尝试使用 Nest DI 系统,那么您不能自己调用​​ new ZohoStore(),因为 Nest 没有机会实例化 ZohoStore 的依赖项。

您需要在某个 NestJS 模块中将其注册为提供程序,然后如果您愿意,可以检索 由 NestJS 创建的实例

https://docs.nestjs.com/providers#property-based-injection https://docs.nestjs.com/fundamentals/module-ref#retrieving-instances https://docs.nestjs.com/techniques/configuration#using-in-the-maints

【讨论】:

【参考方案2】:

只需添加到@Micael 的回复中,您需要执行以下操作:

    将商店添加到将使用 DI 的模块中:
@Module(
  imports: [MongooseModule.forFeature([ name: ZohoToken.name, schema: ZohoTokenSchema ])],
  exports: [ZohoStore, ZohoService],
  providers: [ZohoStore, ZohoService],
  controllers: [ZohoController]
)
export class ZohoModule 
    务必将@Injectable()装饰器添加到Store类并使用DI注入模型:
@Injectable()
export class ZohoStore implements TokenStore 
  constructor(@InjectModel(ZohoToken.name)
  private readonly tokenModel: Model<ZohoTokenDocument>);
    在服务类中,如下引用ZohoStore,这样当您准备好使用它时,您只需从类成员变量中调用this.zohoStore,而不是尝试使用new 实例化它:
@Injectable()
export class ZohoService 
  private zohoStore: ZohoStore;

  constructor(private moduleRef: ModuleRef) 

  onModuleInit() 
    this.zohoStore = this.moduleRef.get(ZohoStore);
  

【讨论】:

以上是关于Nest.js 模型依赖注入与 Mongoose 没有构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Nest.js 获取注入器实例

Nest.js 为模型创建静态和实例函数的方法是啥?

Nest.js/Mongoose:为啥我的预保存钩子无法触发?

在 Nest.JS 中将服务注入警卫

nest.js学习

前端工程师梭哈初体验(基于Nest.js写服务端代码)