You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[ ] bug report => search github for a similar issue or PR before submitting
[X] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
I've been working with angular2/4 now for about half a year and used several libraries.
One thing i often came accross was the cumbersome instance scope especially if you have multiple modules. Currently many libraries provide static forRoot() Methods of a module or with Root-/NonRootModules so that a singleton is created. I you forget this you either don't get any instance or end up with too many instances which might lead to unexpected behavior.
Expected behavior
I would expect a more explicit instance scope, i.e.
I believe your understanding here is slightly off.
Providers provided on a non lazy loaded module will always be singletons for that module
Providers provided on a component will have a new instance per instance of that component
When initializing a lazy module the providers of the parent will be copied into the lazy module and the providers provided in the lazy module will be scoped to the lazy module but still singletons in that context
I still think you misunderstand it. Currently what determines what kind of service a particular service is, is where that service is provided, as I explained above.
So by adding this feature you're fundamentally changing how services work with the injector since where they're provided will no longer matter
Currently what determines what kind of service a particular service is, is where that service is provided, as I explained above.
And that's a problem - at least in some situations. Today where a service is provided is tightly bound to how many instances of a service will be created. Even though that makes sense if you want to have Injector scopes, where and how many are not strictly related from a conceptual perspective of DI in general.
Consider non-singleton services for a moment: let's say there's an app-wide service FooServiceImpl which is used by almost every component (injection target) but implemented in a way that if it would be shared as a singleton it would cause injection targets to maliciously affect each other. Since it is an app-wide service I would like to provide it, e.g via the root injector or any injector responsible for a particular target scope and tell it to create a separate instance for each injection target (singleton: false).
All proposals I have found to achieve this is, to add a provide: [FooServiceImpl] declaration on each injection target (a Component or one of its parent components) because its impossible to configure on the root level nor on the service implementation itself how many instances to create. That's irritating, because the whole point of DI is to decouple injection targets from concrete implementations of a service interface. But it is the service's implementation which causes service clients to affect each other if they share the same instance. There might exist stateless implementations which were usable as a singleton - who knows. The point is, injection targets shouldn't have any knowledge about how the service they get injected is implemented nor instantiated and thus shouldn't require a provide declaration just to get their own instance of the service. They should just take any instance they get and work with it, without any knowledge about whether another component might get the same instance or a different one. Its the interface author (who formulates the interface contract) or the implementor who decide how many instances should be created but not the injection targets. Consequently its either the service implementation where we should tell how many instances to create (@Mscu variant2) or where an injection token (= service interface) is mapped to a concrete implementation (provider objects) (@Mscu variant1).
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
There are two separate concerns being discussed in this request, if I'm reading the issue description and comments correctly:
Prevent a service from being provided if its parent injector already includes the provider. This can be achieved today using @Injectable({ providedIn: 'root' }).
Activity
Toxicable commentedon May 27, 2017
I believe your understanding here is slightly off.
Providers provided on a non lazy loaded module will always be singletons for that module
Providers provided on a component will have a new instance per instance of that component
When initializing a lazy module the providers of the parent will be copied into the lazy module and the providers provided in the lazy module will be scoped to the lazy module but still singletons in that context
mscudlik commentedon May 28, 2017
I think i understood how it works and i'm just saying it could be way easier, especially if you have 15+ own modules and use several libraries
Toxicable commentedon May 28, 2017
I still think you misunderstand it. Currently what determines what kind of service a particular service is, is where that service is provided, as I explained above.
So by adding this feature you're fundamentally changing how services work with the injector since where they're provided will no longer matter
about-code commentedon Jun 1, 2017
And that's a problem - at least in some situations. Today where a service is provided is tightly bound to how many instances of a service will be created. Even though that makes sense if you want to have Injector scopes, where and how many are not strictly related from a conceptual perspective of DI in general.
Consider non-singleton services for a moment: let's say there's an app-wide service
FooServiceImplwhich is used by almost every component (injection target) but implemented in a way that if it would be shared as a singleton it would cause injection targets to maliciously affect each other. Since it is an app-wide service I would like to provide it, e.g via the root injector or any injector responsible for a particular target scope and tell it to create a separate instance for each injection target (singleton: false).All proposals I have found to achieve this is, to add a
provide: [FooServiceImpl]declaration on each injection target (a Component or one of its parent components) because its impossible to configure on the root level nor on the service implementation itself how many instances to create. That's irritating, because the whole point of DI is to decouple injection targets from concrete implementations of a service interface. But it is the service's implementation which causes service clients to affect each other if they share the same instance. There might exist stateless implementations which were usable as a singleton - who knows. The point is, injection targets shouldn't have any knowledge about how the service they get injected is implemented nor instantiated and thus shouldn't require aprovidedeclaration just to get their own instance of the service. They should just take any instance they get and work with it, without any knowledge about whether another component might get the same instance or a different one. Its the interface author (who formulates the interface contract) or the implementor who decide how many instances should be created but not the injection targets. Consequently its either the service implementation where we should tell how many instances to create (@Mscu variant2) or where an injection token (= service interface) is mapped to a concrete implementation (provider objects) (@Mscu variant1).angular-robot commentedon Jun 4, 2021
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
angular-robot commentedon Jun 25, 2021
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
JoostK commentedon Oct 6, 2021
There are two separate concerns being discussed in this request, if I'm reading the issue description and comments correctly:
@Injectable({ providedIn: 'root' }).angular-automatic-lock-bot commentedon Nov 6, 2021
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.