I do have a module "FileUpload". The included upload service "UploadService" gets a service injected with the interface "RequestService".
I do have two other modules: FileManager1 and FileManager2. Each file manager provides an own implementation of a service with the interface "RequestService" in provides it in the token "REQUEST_SERVICE".
I created a stackblitz for this simplified scenario: https://angular-wufhd5.stackblitz.io
To create for each module usage an own instance of the file-upload service, I moved the service provider from the file-upload.module.ts into the component drop-zone.component.ts. This works as you can see in the console.log.
If you click on "Click me", the console.log output ist for FileManager1 and FileManager2 the same tho. ("Url2").
For FileManager1 it should be Url1, for FileManager2 it should be Url2.
What would be a clean solution for this requirement? I would like to avoid multiple tookens beside one "REQUEST_SERVICE".
Thank you very much!
Output now after click events:
A new service has been created....
A new service has been created....
Angular is running in development mode. Call enableProdMode() to enable production mode.
Upload file to:
Url2
Upload file to:
Url2
Output should:
A new service has been created....
A new service has been created....
Angular is running in development mode. Call enableProdMode() to enable production mode.
Upload file to:
Url1
Upload file to:
Url2
CodePudding user response:
Angular only creates ModuleInjectors
for the RootModule
(AppModule) and lazy-loaded modules. The providers of directly imported modules get escalated to the first lazy-loaded module in the hierarchy or if there's none to the RootModule.
Since you are importing both FileManager1Module
and FileManager2Module
directly in the AppModule
and in that order. Angular first escalates to the AppModule
the provider for REQUEST_SERVICE
that you have in the FileManager1Module
. And then that provider gets overwritten with the one that you have in the FileManager2Module
. That's why both print "Url2" to the console.
To solve it, you have two options:
- Declare the
REQUEST_SERVICE
as a component level provider. (InFileManager1Component
andFileManager2Component
) - Or if you are planning to use the Router, Lazy-load the modules.
cheers
CodePudding user response:
You could try to specific RequestService per module provider like this:
@Injectable({
providedIn: FileManager1Module ,
})
export class RequestService1 implements RequestService{
}
@Injectable({
providedIn: FileManager2Module ,
})
export class RequestService2 implements RequestService{
}
And in every place within those modules you can inject them by interface RequestService.