You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Logger依赖注入报错:Cannot read properties of undefined (reading 'Logger')

将Logger依赖注入MongoDBConnector时出现TypeError错误

当尝试将Logger依赖注入到MongoDBConnector类时,抛出以下错误:

E:\my_site\src\common\database\MongoDBConnector.ts:11
constructor(@inject(COMMON_TYPES.Logger) logger: ILogger) {
^TypeError: Cannot read properties of undefined (reading 'Logger')
at Object.<anonymous> (E:\my_site\src\common\database\MongoDBConnector.ts:11:38)
at Module._compile (node:internal/modules/cjs/loader:1469:14)
at Module.m._compile (E:\my_site\node_modules\ts-node\src\index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
at Object.require.extensions.<computed> [as .ts] (E:\my_site\node_modules\ts-node\src\index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1288:32)
at Function.Module._load (node:internal/modules/cjs/loader:1104:12)
at Module.require (node:internal/modules/cjs/loader:1311:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (E:\my_site\src\common\common_injection_container.ts:4:1)

相关代码文件

inversify.config.ts

import { Container, ContainerModule } from 'inversify';
import { commonContainer, COMMON_TYPES } from '../common_injection_container';
import { ILogger } from '../../common/interfaces/ILogger';

const appContainer = new Container();

appContainer.load(commonContainer);

const logger = appContainer.get<ILogger>(COMMON_TYPES.Logger);

interface ContainerDefinition {
    container: ContainerModule;
    name: string;
}

const containers: ContainerDefinition[] = [
];

containers.forEach(({ container, name }) => {
    try {
        appContainer.load(container);
        logger.info(`${name} container loaded successfully`);
    } catch (error) {
        logger.error(`Failed to load ${name} container`);
        if (error instanceof Error) {
            logger.trackError(error);
        } else {
            logger.error('An unknown error occurred while loading the container.');
        }
    }
});

export { appContainer };

common_injection_container.ts

import { ContainerModule, interfaces } from 'inversify';
import { ILogger } from './interfaces/ILogger';
import Logger from './utils/Logger';
import { MongoDBConnector } from './database/MongoDBConnector';


const COMMON_TYPES = {
    Logger: Symbol.for('Logger'), 
    MongoDBConnector: Symbol.for('MongoDBConnector'), 
};

const commonContainer = new ContainerModule((bind: interfaces.Bind) => {
    bind<ILogger>(COMMON_TYPES.Logger).to(Logger).inSingletonScope();
    bind<MongoDBConnector>(COMMON_TYPES.MongoDBConnector).to(MongoDBConnector);
});

export { commonContainer, COMMON_TYPES };

MongoDBConnector.ts

import mongoose from 'mongoose';
import { inject, injectable } from 'inversify';
import { ILogger } from '../../common/interfaces/ILogger';
import { COMMON_TYPES } from '../../common/common_injection_container';

@injectable()
export class MongoDBConnector {
    private logger: ILogger;

    constructor(@inject(COMMON_TYPES.Logger) logger: ILogger) {
        if (!logger) {
            throw new Error('Logger not found during MongoDBConnector injection');
        }
        this.logger = logger;
    }

    public async connectToMongoDB(): Promise<void> {
        try {
            await mongoose.connect(process.env.MONGODB_URI!, {
                serverSelectionTimeoutMS: 30000, 
            });
            this.logger.info('Connected to MongoDB'); 
        } catch (error: any) {
            if (error instanceof Error) {
                this.logger.error('Could not connect to MongoDB'); 
                this.logger.error(`Error details: ${error.message}`); 
            } else {
                this.logger.error('Could not connect to MongoDB with an unknown error');
            }
            throw error; 
        }
    }
}

问题原因

错误源于循环模块导入:

  • common_injection_container.ts 导入了 MongoDBConnector
  • MongoDBConnector.ts 又反向导入了 common_injection_container.ts

Node.js加载模块时,会先处理common_injection_container.ts,此时它会触发MongoDBConnector的加载;而MongoDBConnector需要访问COMMON_TYPES.Logger,但此时COMMON_TYPES还未被common_injection_container.ts完成导出,导致COMMON_TYPES为undefined,最终抛出错误。


解决方案

方案1:拆分COMMON_TYPES到独立文件(推荐)

将类型定义从容器配置文件中分离,彻底避免循环引用:

  1. 创建common_types.ts文件:
export const COMMON_TYPES = {
    Logger: Symbol.for('Logger'), 
    MongoDBConnector: Symbol.for('MongoDBConnector'), 
};
  1. 修改common_injection_container.ts:
import { ContainerModule, interfaces } from 'inversify';
import { ILogger } from './interfaces/ILogger';
import Logger from './utils/Logger';
import { MongoDBConnector } from './database/MongoDBConnector';
import { COMMON_TYPES } from './common_types';

const commonContainer = new ContainerModule((bind: interfaces.Bind) => {
    bind<ILogger>(COMMON_TYPES.Logger).to(Logger).inSingletonScope();
    bind<MongoDBConnector>(COMMON_TYPES.MongoDBConnector).to(MongoDBConnector);
});

export { commonContainer };
  1. 修改MongoDBConnector.ts:
import mongoose from 'mongoose';
import { inject, injectable } from 'inversify';
import { ILogger } from '../../common/interfaces/ILogger';
import { COMMON_TYPES } from '../../common/common_types';

@injectable()
export class MongoDBConnector {
    // 其余代码保持不变
}
  1. 修改inversify.config.ts:
import { Container, ContainerModule } from 'inversify';
import { commonContainer } from '../common_injection_container';
import { COMMON_TYPES } from '../common_types';
import { ILogger } from '../../common/interfaces/ILogger';

// 其余代码保持不变

方案2:延迟导入(临时方案)

若不想拆分文件,可使用异步延迟导入MongoDBConnector,但会增加代码复杂度:

修改common_injection_container.ts:

import { ContainerModule, interfaces } from 'inversify';
import { ILogger } from './interfaces/ILogger';
import Logger from './utils/Logger';

const COMMON_TYPES = {
    Logger: Symbol.for('Logger'), 
    MongoDBConnector: Symbol.for('MongoDBConnector'), 
};

const commonContainer = new ContainerModule(async (bind: interfaces.Bind) => {
    bind<ILogger>(COMMON_TYPES.Logger).to(Logger).inSingletonScope();
    
    // 延迟导入MongoDBConnector
    const { MongoDBConnector } = await import('./database/MongoDBConnector');
    bind<MongoDBConnector>(COMMON_TYPES.MongoDBConnector).to(MongoDBConnector);
});

export { commonContainer, COMMON_TYPES };

同时修改inversify.config.ts的容器加载方式:

// 替换原加载代码
await appContainer.loadAsync(commonContainer);

内容的提问来源于stack exchange,提问作者NoBody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:24:51