Home > Back-end >  Angular DI: Instance of each service for each modul-usage
Angular DI: Instance of each service for each modul-usage

Time:02-25

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. (In FileManager1Component and FileManager2Component)
  • 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.

  • Related