-
Notifications
You must be signed in to change notification settings - Fork 27.1k
providedIn custom scopes using tokens #68007
Description
Which @angular/* package(s) are relevant/related to the feature request?
core
Description
Currently there are two main ways to scope injectables in Angular:
- Provided in root
- Explicit provider array
The former offers advantages in terms of tree-shaking (the class is only included in the bundle if requested). However, as soon as one dependency cannot be provided in root, all of its dependants must be provided using an explicit provider array.
I would like a hybrid solution, where I do not need to define all providers up-front, but the providers are still not globally scoped, and so can depend on other providers.
Use cases
-
Scoped storage:
- If there is part of the component tree that is based around processing a specific entity, this can be provided, or stored in a scoped provider.
- Any other services can then safely depend on this provider, without all needing to be explicitly provided
- These providers then can be lazy-loaded if used in deferred components, or entirely omitted from the bundle if not used anywhere.
- The code becomes more maintainable: it is less likely that old providers are left in provider arrays. The scope does not require knowledge of all providers defined in nested folders.
-
Web components (Angular elements)
- These elements will often receive globally relevant inputs, such as language or Auth tokens, as part of a micro-Frontend architecture.
- These inputs are needed in many different services, so these services, none of which can be globally scoped.
Proposed solution
This proposal seeks to add a new type of providedIn: a ProviderScopeToken.
ProviderScopeToken are not generic, and take only a debugging string as a parameter. They can then be included in a providers array, as well as being passed as providedIn to an Injectable or InjectionToken.
When an Injectable or InjectionToken is injected, the injection hierarchy is searched upwards, checking for where it has been provided. However, if this injectable is providedIn a ProviderScopeToken, we additionally search for injectors that provide this scope. When it is encountered, the factory or class is instantiated, or the useExisting is evaluated.
Alternatives considered
Listing all providers has proven to be error-prone, as old providers are not cleared up when they are no longer needed.
I’ve not found a way to implement this feature in userland yet, but would be intrigued to hear if there is a way. It would possibly be achievable using a custom inject function, by rebuilding logic of an injector within the ProviderScopeToken.