Skip to content

Provide control over route-scoped provider lifetime when only route parameters change #70101

Description

@SeyaSchmassmann

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

router

Description

Summary

withExperimentalAutoCleanupInjectors currently ties the lifetime of route injectors to the reused route configuration, not to the logical route context.

When navigating between different parameter values of the same route, the existing route injector is reused instead of being destroyed and recreated.

For example:

/area/123/overview
    ↓
/area/456/overview

Although the route configuration is identical, the logical route context has changed. However, route-scoped providers continue to live in the existing injector.

Use case

Some applications use route-scoped providers to expose state or services that are specific to the current route context, for example by providing a context object derived from route parameters.

The lifetime of these providers often represents a logical route context rather than just the route configuration itself. When navigating between different parameter values of the same route, such as /area/123 and /area/456, the logical context changes even though the route configuration remains the same.

In these cases, route-scoped providers should represent the new context and be recreated accordingly. However, because the route injector is reused, provider instances are not recreated and continue to expose state from the previous route context. Without a way to control route injector lifetime independently from route reuse, applications can end up with stale provider state despite navigating to a different logical resource.

Current limitation

At first glance, RouteReuseStrategy.shouldDestroyInjector() appears to provide the necessary extension point. However, it does not offer the same level of control as RouteReuseStrategy.shouldReuseRoute(), which determines whether routed components are recreated.

The injector destruction decision is also coupled to Angular's internal route tracking. Currently, the injector is only considered for destruction when the route is no longer active:

const shouldDestroyCurrentRoute =
  inheritedForceDestroy ||
  !!(
    (route._injector || route._loadedInjector) &&
    !activeRoutes.has(route) &&
    ((strategy as ExperimentalRouteReuseStrategy).shouldDestroyInjector?.(route) ?? false)
  );

When only route parameters change, the route remains active, so !activeRoutes.has(route) is false. As a result, shouldDestroyInjector() is never able to trigger recreation of the injector, even if an application would like a new route-scoped provider lifetime for the new route context.

This makes shouldDestroyInjector() fundamentally less powerful than shouldReuseRoute(), as applications cannot decide that a parameter change should result in a fresh injector while still reusing the route configuration.

Is the current behavior intentional? If so, would the Angular team consider exposing an extension point similar to RouteReuseStrategy.shouldReuseRoute() that allows applications to control the lifetime of route-scoped injectors independently from route reuse?

Proposed solution

It would be helpful to have one of the following:

  • An extension point that determines whether a route injector should be reused, analogous to RouteReuseStrategy.shouldReuseRoute().
  • A configuration option for withExperimentalAutoCleanupInjectors that recreates injectors when route parameters (or optionally query parameters) change.
  • Another extensibility mechanism that allows applications to define the lifetime of route-scoped providers independently of route reuse.

Alternatives considered

no

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions