Using multiple instances of the same service

Solution 1:

Angular DI maintains a single instance per provider. In your case if you have two constructor parameters with the same type, they resolve to the same instance.

What you can do is to provide a factory function (different from a simple useFactory provider event though it uses it as well)

(Example copied from https://stackoverflow.com/a/37517575/217408)

{ provide: EditorService, useFactory: 
    (dep1, dep2) => {
        return (x) => { 
            new EditorService(x, dep1, dep2);
        }
    }, deps: [Dep1, Dep2]
})

....

constructor(@Inject(EditorService) editorServiceFactory: any) {
  let editorService1 = editorServiceFactory(1);
  let editorService2 = editorServiceFactory(2);
}

If you have a fixed number of instances this should work:

{ provide: 'instance1', useClass: EditorService },
{ provide: 'instance2', useClass: EditorService },
export class SomeComponent {
    constructor(
        @Inject('instance1') private _appleEditorService: EditorService,
        @Inject('instance2') private _pearEditorService: EditorService) {}
}

Solution 2:

maybe rethink your design

I think you might have to rethink your design altogether then. What's the point of having two variables that point to the exact same EditorService? If they share the same implementation.

Inheritance solution

A solution to this would perhaps be to use Inheritance. I have not seen your services so I am not sure what they do, but from this code I am assuming that the "apple" functionality and the "pear" functionality is actually different. Then this is indicating you might have some design issues, and your EditorService might be doing too much. Perhaps you could move the code that is similar for both Apples and Pears to a service called EditorService and then have two classes extend this. an AppleEditorServiceand a PearEditorService.

Use general fruitService

Just to talk a bit more about why I think you might need to rethink your design. Let's assume that appels and pears actually do have the same functionality. So the EditorServicedoes the same. You want one variable to be used for 'Apples' and one for 'Pears'. If I see that code (assume other people work on your team), and I notice that both variables point to the same service. (Services are singletons), I would just be tempted to remove that and make something like fruitService : EditorServiceor something of the likes.

Either way your question makes me think the design should be changed. You don't want two instances of the service, services are singleton and although you could find ways around it, I don't think that's really the solution to your problem.


But as I have mentioned before. Think about your design. Do you really need two child-services, or can you solve it differently? Can you have apples and pears just subclass fruit? Can you just use one variable 'fruitService' instead of both apples/pears? What happens when you want to store "Strawberries" as well in the future? Having a bunch of variables refer to the same service (because they do the same thing) but with different variable names is not a good idea. Imagine seeing this in code

 appleService = EditorService;
 pearService = EditorService;
 starwberryService = EditorService;
 lemonService = EditorService;
 ...
 guavaService = EditorService;

Would this not indicate something is weird with the code? I can imagine (you didn't provide the code at this point) that you store an Array of the fruitInstances. But then maybe a fruitService could work and then store fruitService.store(Apple a) and put that in an array of 'fruit'. Use a 'filter' to get the right fruit from the array shouldn't be too hard.

^ This is just written without having more of your code to go on. If you edit your question, some things might not hold up anymore.