A couple things to note here:
1. providedIn: 'root'
is a nice feature but it probably wasn't built for you
As @Leon mentioned, this feature is meant to make services more tree shakeable. It is not meant to completely replace using the providers: []
property of a module. It is an option mostly meant for library developers, not as much for application developers.
Imagine this scenario:
You created a service a few months ago and now your app is no longer using it. You know it's not using it because it's your app and you have full knowledge and control over the codebase. What do you do to that service?
A) Make sure it's using providedIn: 'root'
so that Angular can tree shake it out of the bundle since you're not using it anymore
B) Delete the service.
My guess is B!
Imagine another scenario:
You are using a 3rd party Angular module from an npm package. That module has 12 difference services you can use in your app to take advantage of its features. Your app doesn't need all those features so you only inject 3 of those service types into your application components or services.
How do you resolve this?
A) Fork the repository so you can remove all the services your app doesn't use so you don't have to include them in your bundle.
B) Ask the project owner to use providedIn: 'root'
. If the library author used providedIn: 'root'
the services you don't use don't have an impact on your bundle size and they can stay in the npm package/Angular module for other teams to use if they need them.
My guess is B!
2. providedIn: 'root'
doesn't work for interceptors
Interceptors are a multi
DI token service which means you can provide multiple values for the same DI token. That token is HTTP_INTERCEPTORS
. The @Injectable({...})
decorator exposes no api for providing the decorated type for a different token the way the @NgModule({...})
decorator does.
This means you can't tell Angular Anywhere you would normally ask for 'HTTP_INTERCEPTORS' add this service to the set of values to use instead
using the @Injectable({...})
decorator.
You can only do this in a @NgModule({...})
decorator.
3. Providing interceptors is order dependent
Interceptors are a pipeline and the order they are provided in matters in determining the order they get access to the request object (to modify or inspect) and the response object (to modify or inspect).
While some interceptors might be order agnostic you still probably want some determinism in that ordering.
So even if providedIn: 'root'
worked for interceptors the order they would be provided in would be determined by the resolution order of types during the Angular compile step - probably not what you want.
Instead providing them in the providers: []
array in an @NgModule({...})
decorator means you can explicitly set the order they will be called in.