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
Which @angular/* package(s) are relevant/related to the feature request?
router
Description
Summary
withExperimentalAutoCleanupInjectorscurrently 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:
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/123and/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 asRouteReuseStrategy.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:
When only route parameters change, the route remains active, so
!activeRoutes.has(route)isfalse. 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 thanshouldReuseRoute(), 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:
RouteReuseStrategy.shouldReuseRoute().withExperimentalAutoCleanupInjectorsthat recreates injectors when route parameters (or optionally query parameters) change.Alternatives considered
no