Skip to content

providedIn custom scopes using tokens #68007

@xsanda

Description

@xsanda

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

Currently there are two main ways to scope injectables in Angular:

  1. Provided in root
  2. 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

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimecore: difeatureLabel used to distinguish feature request from other issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions