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

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],
    };
  }
}

原理说明

  1. 动态模块需要显式声明所有需要暴露的控制器与提供者,否则会覆盖原模块的配置,导致Nest无法找到AlarmsService及其依赖。
  2. 传入的InfrastructureModule已经是AlarmInfrastructureModule.use()返回的动态模块,包含了对应持久化层的配置与导出的AlarmRepository,无需重复导入AlarmInfrastructureModule。
  3. 修正后,AlarmsModule的动态模块既保留了业务逻辑层的提供者与控制器,又正确导入了提供AlarmRepository的基础设施模块,依赖注入即可正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:47:34