Max Koretskyi
Max Koretskyi

Reputation: 105547

How does intermediary module providers fit into injector tree

This tutorial doesn't talk much about how modules fit in the injector tree except for the this phrase:

All requests bubble up to the root NgModule injector that we configured with the bootstrapModule method.

Does it mean that if a provider is not found on any component up the tree, only the root module is checked and no other intermediary module is checked? For example, the picture below shows the component tree with one root component and with components 3 and 4 being declared in it's own module. The root module has it's own provider and the red module has it's own provider. When component 3 requests the service, is the provider on red module ignored and the provider on parent component checked and if not found than provider on root module is returned? enter image description here

Upvotes: 1

Views: 61

Answers (1)

Günter Zöchbauer
Günter Zöchbauer

Reputation: 658037

I think you are looking for https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-module-provider-visibility

Why is a service provided in a feature module visible everywhere? Providers listed in the @NgModule.providers of a bootstrapped module have application scope. Adding a service provider to @NgModule.providers effectively publishes the service to the entire application.

When we import a module, Angular adds the module's service providers (the contents of its providers list) to the application root injector.

This makes the provider visible to every class in the application that knows the provider's lookup token.

This is by design. Extensibility through module imports is a primary goal of the Angular module system. Merging module providers into the application injector makes it easy for a module library to enrich the entire application with new services. By adding the HttpModule once, every application component can make http requests.

However, this can feel like an unwelcome surprise if you are expecting the module's services to be visible only to the components declared by that feature module. If the HeroModule provides the HeroService and the root AppModule imports HeroModule, any class that knows the HeroService type can inject that service, not just the classes declared in the HeroModule.

The providers of the modules are added to the root scope. Duplicates are discarded. This means the providers are found from your entire application, except when they are overridden on components or lazy loaded modules. Lazy loaded modules get their own root scope.

If the red module is lazy loaded then component 3 will get the provider from this module, if it's eagerly loaded the providers of the red module are added to the root scope of the application and component 3 will get it from there. This is all related to providers added by @NgModule()

Providers added to @Component() or @Directive() are not hoisted to any root scope. DI looks from the component that has a dependendency on its parent and its parents parent, ... for a provider and at last in the root scope of the application or in the root scope of the lazy loaded module if the component is part of one.

Upvotes: 1

Related Questions