A brief note about the root application injector

When Angular bootstraps, it creates a default application-wide injector called the root application injector, which is linked to AppModule (that is, the root application module). By default, service providers are registered in it.

To register a service globally (that is, to make it injectable anywhere in your application), you can use the providedIn: 'root' property of the @Injectable decorator, as we did in the previous section. This will register the service in the root application injector.

To be thorough, you should know that Angular's DI framework defines a tree of injectors, which is somewhat akin to the change detection tree. Similarly, the injector tree reflects and lies next to the component tree.

When the injector of a component cannot find a required dependency, then the parent injector is queried, and so on, until the root application injector is reached. This process is called injector bubbling (to make the parallel with DOM event bubbling) and is explained in detail here: https://angular.io/guide/hierarchical-dependency-injection#injector-bubbling.

As you can guess, the root application injector sits at the top of that tree. This root injector is used for most services. This is intuitive because most services should be stateless, hence it is better to maximize the reuse of existing instances instead of having to create new instances depending on where things need to be injected. Sometimes, though (usually for performance reasons), it actually makes sense to register some providers locally within specific modules that can be loaded lazily or even tree-shaken (that is, removed) if not needed, resulting in lighter application bundles.

You can register a service locally in a specific module either by using providedIn: SomeModule or by adding the provider to the providers property of the @NgModule() decorator. You can learn more about that here: https://medium.com/@tomastrajan/total-guide-to-angular-6-dependency-injection-providedin-vs-providers-85b7a347b59f.

If you want a new instance of a given dependency each time a component is instantiated, then you can register the provider through the providers array property of the @Component decorator at https://angular.io/api/core/Component.

Obviously, the reality is more complicated than this and there are quite a few subtleties; however, we'll stop here since this should already have given you a pretty solid understanding of what DI is and how it works in Angular.