无法在“GetModelService”构造函数的位置 #0 注入依赖项“modelRepository”原因:无法读取未定义的属性“名称”

问题描述

我一直在使用 sequelize-typescripttsyringe 进行重构工作,在这里我发现了一个非常有趣的错误。 通常,我的所有存储库容器都在正常注册并使用以下设置正确实例化:

  • 我将反射元数据导入到我的应用程序根目录及其后的 tsyringe 容器

    import 'reflect-Metadata';
    import 'dotenv/config';
    import express,{ Request,Response,NextFunction } from 'express';
    ...
    import '@shared/infra/sequelize/index'; // default sequelize connection
    import '@shared/container/index';
    
  • 容器/索引内部是以下代码,我使用 sequelize-typescript 制作存储库。

    
    import { container } from 'tsyringe';
    
    import IUsersRepository from '@modules/users/repositories/IUsersRepositories';
    import UsersRepository from '@modules/users/infra/sequelize/repositories/UserRepository';
    ...
    import IModelRepository from '@modules/model/repositories/IModelRepository';
    import ModelRepository from '@modules/model/infra/sequelize/repositories/ModelRepository';
    
    container.registerSingleton<IUsersRepository>(
      'UsersRepository',UsersRepository,);
    ...
    container.registerSingleton<IModelRepository>(
      'ModelRepository',ModelRepository,);
    
  • 然后我用 express 完成所有的路由:

    import { Router } from 'express';
    import bdDecider from '@shared/infra/http/middlewares/bdDecider';
    import ensureAuthenticated from '@modules/users/infra/http/middlewares/EnsureAuthenticated';
    import UserRouter from '@modules/users/infra/http/routes/user.routes';
    ...
    import ModelRouter from '@modules/model/infra/http/routes/model.routes';
    
    const routes = Router();
    
    routes.use('/sessions',SessionRouter);
    routes.use(ensureAuthenticated);
    routes.use(bdDecider); //bdDecider as it says gets the logged on user bdConfig so i can connect to it
    routes.use('/model',ModelRouter);
    
  • 所以我们去调用container.resolve()

    的路由
    import { container } from 'tsyringe';
    import { Response,Request } from 'express';
    import ShowModelsService from '@modules/invoices/services/ShowModelsService';
    
    export default class ShowModelsController {
      public async show(req: Request,res: Response): Promise<Response> {
        const { id } = req.params;
    
        const showModelsService = container.resolve( //it calls the model service
          ShowModelsService,);
    
        const models = await showModelsService.execute(
          id,);
    
        return res.json(models);
      }
    }
    
  • 这是他调用的服务

    import IModelRepository from '@modules/model/repositories/IModelRepository';
    import AppError from '@shared/errors/AppError';
    import { inject,injectable } from 'tsyringe';
    import IModelDTO from '../dtos/IModelDTO';
    
    type IResponse = IModelDTO;
    
    @injectable()
    export default class ShowModelService {
      constructor(
        @inject('ModelRepository')
        private modelRepository: IModelRepository,) {}
    
      public async execute(id: string): Promise<IResponse> {
        const model = await this.modelRepository.get_models(
          id,);
    
        if (!model) {
          throw new AppError('Model not found!',404);
        }
    
        return model;
      }
    }
    
  • 直到那里一切正常并且工作正常,但是当我尝试使用 sequelize 将该模型与另一个模型相关联时。 Tsyringe 停止能够正确注入依赖项并给出标题错误消息。这是我试图关联的模型。

    import Model from '@modules/model/infra/sequelize/entities/Model';
    import { DataTypes } from 'sequelize';
    import { Sequelize } from 'sequelize-typescript';
    import User from '../entities/User';
    export default (sequelize: Sequelize): void => {
    Model.init(
        {
          primary: {
            allowNull: false,autoIncrement: true,primaryKey: true,type: DataTypes.INTEGER,},camp1: DataTypes.DECIMAL(20,2),camp2: DataTypes.DATE,{
          tableName: 'tbl_model',sequelize,);
      Model.hasMany(User);
    }
    
  • 如果我删除Model.hasMany(User);”,它会恢复正常并发生注入,我很困惑不知道发生了什么......

  • 顺便说一下,这里是我的模型存储库

    import IModelRepository from '@modules/model/repositories/IModelRepository';
    import AppError from '@shared/errors/AppError';
    import { connection } from '@shared/infra/http/middlewares/bdDecider';
    import { Repository } from 'sequelize-typescript';
    import IModelDTO from '@modules/model/dtos/IModelDTO';
    import initModel from '../utils/initInvoice';
    import initUser from '../utils/initItem';
    import Model from '../entities/Model';
    import User from '../entities/User';
    
    export default class ModelRepository implements IModelRepository {
      private ormRepository: Repository<Model>;
    
      constructor() {
        if (!connection) {
          throw new AppError(
            `You don't have a client settled on your user credentials or you don't have a client settled or both`,);
        }
        initModel(connection); // it Model.init() the model with the hasmany association
        initUser(connection); // it User.init()
        this.ormRepository = connection.getRepository(Model);
      }
      public async get_models(
        id: string,): Promise<IModelDTO | null> {
        const models = await this.ormRepository.findOne({
          where: { id },include: [
            {
              model: User,],});
        return models;
      }
    }
    
    
  • 如果信息太多,我很抱歉,但我尝试提供尽可能多的信息,以便有人可以帮助我..但老实说,我对找到解决方案有点怀疑,可能我会必须将此方法与此模型分离并尝试单独执行。正如您所注意到的,我更改了模型的名称,因此我可能拼错了某些内容,但不要担心实际代码中没有拼写错误,因为此错误仅在我将“Model.hasMany(User);添加到 {{1 }} 功能。希望有人能够帮助我,我会在附近的任何问题不要害怕问。 :)

解决方法

哦,我想出了一个解决方案。最好在调用 container.resolve() 之前初始化模型。出于某种原因,当您尝试在其中初始化模型时,它看起来像是丢失了引用并且无法注入。但现在一切都很好:)

     constructor() {
        if (!connection) {
          throw new AppError(
            `You don't have a client settled on your user credentials or you don't have a client settled or both`,);
        }
    initModel(connection); 
    initUser(connection); 
    this.ormRepository = connection.getRepository(Model);
  }

所以我只是从存储库构造函数中删除了 initModel 和 initUser 函数,并将其放在调用 container.resolve() 之前的其他位置。