[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I have a module with one controller, that needs a config injected:
@Module({
imports: [],
controllers: [AController],
providers: [ /*ModuleAConfigProvider*/],
})
export class ModuleA {
}
And I have an ApplicationModule which imports the upper module:
@Module({
imports: [ModuleA],
providers: [ModuleAConfigProvider],
})
export class ApplicationModule {
}
When commenting out ModuleAConfigProvider
in the providers of ModuleA nest will complain Nest can't resolve dependencies of the AController
. Remove the comment marks and it works.
When a provider in an imported module is missing it should go up the module tree and find the next matching provider which would be ModuleAConfigProvider
of the ApplicationModules providers.
Angular does the same: Injector Bubbling
One difference in Angular is, that it does the dependency injection on component level.
The motivation is that the imported module could be imported in different applications which can inject different dependencies.
Nest version: 5.0.1
For Tooling issues:
What about trying to add it - ModuleAConfigProvider
- also to exports: []
, in the ApplicationModule
, it should work.
It must be on exports, so can the out side World see it.
No that did not work for me. Still getting the same error.
Hi @vinnichase,
Nest injector works somewhat different than angular one. We don't expose providers globally by default. Instead, all of them are encapsulated inside the module and you have to explicitly export providers. This is an intended behavior explained in the Modules section, here.
Hi @kamilmysliwiec ,
thanks! Yes I got that point and i wanted to edit my last post yesterday to the following: I exposed ModuleA
also with .forRoot(config)
and return it with the ModuleAConfigProvider
which is fed with useValue: config
. This gives me the modularity that I would expect from an IOC container.
However inversion of control means for me that the parent module owns the decision whether or not to override dependencies of the child module, where I think the angular default behavior comes from. I know you provide this possibility by explicitly exporting the provider in ModuleA
which somehow did not work for me. When I add the provider in providers[]
in ModuleA
it will inject this one even if its exported and reprovided in the ApplicationModule
.
I was not sure if I should post this question as a bug report or a question. So could you evaluate if your intended behavior actually works and I would edit the issue afterwards.
@shekohex you propably meant to add ModuleAConfigProvider
to exports: []
in ModuleA right? In ApplicationModule
it makes no sense since its the root module.
Your implementation is very unclear.
The way Nest Dependency Injection works is that the exports
in the Module
will be made available to the outside world and when you import the Module
, you will have access (aka Injectables) to all the Providers
in the exports
array.
Your issue will be solved if you put ModuleAConfigProvider
in the exports
of ApplicationModule
then import ApplicationModule
in ModuleA
. However, that would create a Circular Dependency.
My suggestion would be abstracting all the Config providers to a separate module, maybe ConfigProviderModule
and implement the logic to provide the Config for different Modules there. Put all the Providers in providers
array and exports
array. Then import ConfigProviderModule
in ModuleA
, ModuleB
, ModuleC
etc... to have the ModuleAConfigProvider
available.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Your implementation is very unclear.
The way Nest Dependency Injection works is that the
exports
in theModule
will be made available to the outside world and when you import theModule
, you will have access (aka Injectables) to all theProviders
in theexports
array.Your issue will be solved if you put
ModuleAConfigProvider
in theexports
ofApplicationModule
then importApplicationModule
inModuleA
. However, that would create a Circular Dependency.My suggestion would be abstracting all the Config providers to a separate module, maybe
ConfigProviderModule
and implement the logic to provide the Config for different Modules there. Put all the Providers inproviders
array andexports
array. Then importConfigProviderModule
inModuleA
,ModuleB
,ModuleC
etc... to have theModuleAConfigProvider
available.