1

I have module A and B that depend on each other. Module C depends on Module B. I used forwardRef() for modules A and B, but I didn't for C and B,

// a.module.ts
@Module(
    {
        imports  : [
            forwardRef(() => ModuleB),
            forwardRef(() => ModuleC),
        ],
        providers: [
            ServiceA,
        ],
        exports  : [
            ServiceA,
        ]
    },
)
export class ModuleA {}

// a.service.ts
    constructor(
        @Inject(forwardRef(() => ServiceB)) private readonly serviceB: ServiceB,
        @Inject(forwardRef(() => ServiceC)) private readonly serviceC: ServiceC,
    ) {}

// b.module.ts
@Module(
    {
        imports  : [
            forwardRef(() => ModuleA ),
            ModuleC,
        ],
        providers: [
            ServiceB,
        ],
        exports  : [
            ServiceB,
        ]
    },
)
export class ModuleB {}

// b.service.ts
    constructor(
        @Inject(forwardRef(() => ServiceA)) private readonly serviceA: ServiceA,
                                            private readonly serviceC: ServiceC,
    ) {}

// c.module.ts
@Module(
    {
        imports  : [
            forwardRef(() => ModuleA),
        ],
        providers: [
            ServiceB,
        ],
        exports  : [
            ServiceB,
        ]
    },
)
export class ModuleC {}

// c.service.ts
    constructor(
        @Inject(forwardRef(() => ServiceA)) private readonly serviceA: ServiceA,
    ) {}

It causes a circular dependency between the modules issue, but I can't track the root as module A is in another module, and the modules are deeply integrated/nested. I don't know how circular dependencies are resolved in NestJS, or how to debug better. I read that I should avoid it as much as possible.

Noor_Hasan
  • 97
  • 9
  • Can you show the error you're receiving? And possibly replace the `ModuleA/B/C` with the actual names? Right now it looks like `ModuleB` imports` ModuleC` and `ModuleB` and `ModuleC` both provide a `ServiceB` which may be confusing things – Jay McDoniel Apr 25 '21 at 22:10

1 Answers1

1

I've managed to make it work but you should review your architecture because so many circular dependencies are most certainly a bad pratice.

// app.module.ts
@Module({
  imports: [AModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


// a.module.ts
@Module({
  imports: [BModule, CModule],
  providers: [AService],
  exports: [AService],
})
export class AModule {}

// a.service.ts
@Injectable()
export class AService {
  constructor(
    @Inject(forwardRef(() => BService)) private bService: BService,
    @Inject(forwardRef(() => CService)) private cService: CService,
  ) {}
}

// b.module.ts
@Module({
  imports: [forwardRef(() => AModule), CModule],
  providers: [BService],
  exports: [BService],
})
export class BModule {}

// b.service.ts
@Injectable()
export class BService {
  constructor(
    @Inject(forwardRef(() => AService)) private aService: AService,
    @Inject(forwardRef(() => CService)) private cService: CService,
  ) {}
}

// c.module.ts
@Module({
  imports: [forwardRef(() => BModule), forwardRef(() => AModule)],
  providers: [CService],
  exports: [CService],
})
export class CModule {}

// c.service.ts
@Injectable()
export class CService {
  constructor(@Inject(forwardRef(() => AService)) private aService: AService) {}
}

Module C depends on Module B

You wrote this but in your code, Module C actually depends on module A, so I followed the latter.
Also, in your module C, you have ServiceB in your providers. I guess it's just a copy/paste mistake but it adds to the confusion.

My thought process (I'm not sure I got it right but it works)

AModule is the first imported (in app.module.ts), so it's the first that should be initialized. That's why the imports array does not contain any forward references.

Same with BModule, which should be instanciated in second and finally, CModule (that's why it contains 2 forward references, because it has lowest priority).

After that, I inserted @Inject(forwardRef(() => BService)), until every error like Nest can't resolve dependencies of the AService (BService, ?). was gone.

Haltarys
  • 577
  • 4
  • 10