NestJS依赖注入异常排查:六边形架构实现遇阻
NestJS六边形架构依赖注入问题解决
问题背景
学习NestJS并实现六边形架构时,遇到依赖注入失败问题,代码与讲师完全一致,但报错提示无法解析AlarmsService的AlarmRepository依赖。
相关代码
启动函数
const app = await NestFactory.create( AppModule.register({ driver: 'in-memory' }), ); await app.listen(process.env.PORT ?? 3000); }
应用模块(AppModule)
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AlarmsModule } from './alarms/application/alarms.module'; import { CoreModule } from './core/core.module'; import { ApplicationBootstrapOption } from './common/interfaces/application-bootstrap-option.interface'; import { AlarmInfrastructureModule } from './alarms/infrastructure/alarms-infrastructure.module'; @Module({ imports: [AlarmsModule, CoreModule], controllers: [AppController], providers: [AppService], }) export class AppModule { static register(options: ApplicationBootstrapOption) { return { module: AppModule, imports: [ CoreModule.forRoot(options), AlarmsModule.withInfrastructure( AlarmInfrastructureModule.use(options.driver), ), ], }; } }
告警模块(AlarmsModule)
import { DynamicModule, Module, Type } from '@nestjs/common'; import { AlarmsService } from './alarms.service'; import { AlarmsController } from '../presenters/http/alarms.controller'; import { AlarmFactory } from '../domain/factories/alarm.factory'; import { AlarmInfrastructureModule } from '../infrastructure/alarms-infrastructure.module'; @Module({ controllers: [AlarmsController], providers: [AlarmsService, AlarmFactory], }) export class AlarmsModule { static withInfrastructure(InfrastructureModule: Type | DynamicModule) { return { module: AlarmsModule, imports: [InfrastructureModule, AlarmInfrastructureModule], }; } }
告警基础设施模块(AlarmInfrastructureModule)
import { Module, Type } from '@nestjs/common'; import { OrmAlarmPersistenceModule } from './persistence/orm/orm-persistence.module'; import { InMemoryPersistenceModule } from './persistence/in-memory/in-memory-persistence.module'; import { ApplicationBootstrapOption } from 'src/common/interfaces/application-bootstrap-option.interface'; @Module({}) export class AlarmInfrastructureModule { static use(driver: ApplicationBootstrapOption['driver']) { let persistenceModule: | typeof OrmAlarmPersistenceModule | typeof InMemoryPersistenceModule; if (driver === 'orm') persistenceModule = OrmAlarmPersistenceModule; else persistenceModule = InMemoryPersistenceModule; return { module: AlarmInfrastructureModule, imports: [persistenceModule], exports: [persistenceModule], }; } }
ORM持久化模块
import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AlarmEntity } from './entities/alarm.entity'; import { AlarmRepository } from '../../../application/ports/alarm.repository'; import { OrmAlarmRepository } from './repositories/alarm.repository'; @Module({ imports: [TypeOrmModule.forFeature([AlarmEntity])], providers: [ { provide: AlarmRepository, useClass: OrmAlarmRepository, }, ], exports: [AlarmRepository], }) export class OrmAlarmPersistenceModule {}
内存持久化模块
import { Module } from '@nestjs/common'; import { AlarmRepository } from '../../../application/ports/alarm.repository'; import { InMemoryAlarmRepository } from './repositories/alarm.repository'; @Module({ imports: [], providers: [ { provide: AlarmRepository, useClass: InMemoryAlarmRepository, }, ], exports: [AlarmRepository], }) export class InMemoryPersistenceModule {}
告警服务构造函数
constructor( private readonly alarmRepository: AlarmRepository, private readonly alarmFactory: AlarmFactory, ) {}
错误信息
UnknownDependenciesException [Error]: Nest can't resolve dependencies of the AlarmsService (?, AlarmFactory). Please make sure that the argument AlarmRepository at index [0] is available in the AlarmsModule context.
Potential solutions:
- Is AlarmsModule a valid NestJS module?
- If AlarmRepository is a provider, is it part of the current AlarmsModule?
- If AlarmRepository is exported from a separate @Module, is that module imported within AlarmsModule?
问题原因与解决方案
核心问题
AlarmsModule的withInfrastructure方法返回的动态模块未包含原模块的控制器与提供者,导致Nest无法识别AlarmsService、AlarmFactory的存在,同时多余导入AlarmInfrastructureModule造成重复配置。
修复步骤
修改AlarmsModule的withInfrastructure方法,在动态模块中明确包含原模块的控制器、提供者,并移除多余的AlarmInfrastructureModule导入:
import { DynamicModule, Module, Type } from '@nestjs/common'; import { AlarmsService } from './alarms.service'; import { AlarmsController } from '../presenters/http/alarms.controller'; import { AlarmFactory } from '../domain/factories/alarm.factory'; @Module({ controllers: [AlarmsController], providers: [AlarmsService, AlarmFactory], }) export class AlarmsModule { static withInfrastructure(InfrastructureModule: Type | DynamicModule) { return { module: AlarmsModule, imports: [InfrastructureModule], controllers: [AlarmsController], providers: [AlarmsService, AlarmFactory], }; } }
原理说明
- 动态模块需要显式声明所有需要暴露的控制器与提供者,否则会覆盖原模块的配置,导致Nest无法找到
AlarmsService及其依赖。 - 传入的
InfrastructureModule已经是AlarmInfrastructureModule.use()返回的动态模块,包含了对应持久化层的配置与导出的AlarmRepository,无需重复导入AlarmInfrastructureModule。 - 修正后,
AlarmsModule的动态模块既保留了业务逻辑层的提供者与控制器,又正确导入了提供AlarmRepository的基础设施模块,依赖注入即可正常工作。
内容的提问来源于stack exchange,提问作者Ahmed Ajajeh
相关产品推荐
相关产品推荐

