docs(ngmodule-faq): stronger, clearer advice on where to register providers (#2262)
This commit is contained in:
parent
94a40a1852
commit
38bef16604
|
@ -33,12 +33,13 @@ block includes
|
||||||
* [Can I re-export imported classes and modules?](#q-re-export)
|
* [Can I re-export imported classes and modules?](#q-re-export)
|
||||||
* [What is the _forRoot_ method?](#q-for-root)
|
* [What is the _forRoot_ method?](#q-for-root)
|
||||||
|
|
||||||
Service Providers
|
Service Providers
|
||||||
* [Why is a service provided in a feature module visible everywhere?](#q-module-provider-visibility)
|
* [Why is a service provided in a feature module visible everywhere?](#q-module-provider-visibility)
|
||||||
* [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
|
* [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
|
||||||
* [What if two modules provide the _same_ service?](#q-module-provider-duplicates)
|
* [What if two modules provide the _same_ service?](#q-module-provider-duplicates)
|
||||||
* [How do I restrict service scope to a module?](#q-component-scoped-providers)
|
* [How do I restrict service scope to a module?](#q-component-scoped-providers)
|
||||||
* [Should I add providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
|
* [Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
|
||||||
|
* [Should I add other providers to a module or a component?](#q-component-or-module)
|
||||||
* [Why is it bad if _SharedModule_ provides a service to a lazy loaded module?](#q-why-bad)
|
* [Why is it bad if _SharedModule_ provides a service to a lazy loaded module?](#q-why-bad)
|
||||||
* [Why does lazy loading create a child injector?](#q-why-child-injector)
|
* [Why does lazy loading create a child injector?](#q-why-child-injector)
|
||||||
* [How can I tell if a module or service was previously loaded?](#q-is-it-loaded)
|
* [How can I tell if a module or service was previously loaded?](#q-is-it-loaded)
|
||||||
|
@ -424,14 +425,21 @@ a#q-component-scoped-providers
|
||||||
a#q-root-component-or-module
|
a#q-root-component-or-module
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
### Should I add providers to the root _AppModule_ or the root _AppComponent_?
|
### Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?
|
||||||
|
|
||||||
Most apps launch with an initial set of service providers.
|
.alert.is-helpful
|
||||||
Should we register those providers on the root `AppModule` (`@NgModule.providers`) or
|
:marked
|
||||||
the root `AppComponent` (`@Component.providers`)?
|
Register application-wide providers in the root `AppModule`, not in the `AppComponent`.
|
||||||
|
:marked
|
||||||
|
Lazy-loaded modules and their components can inject `AppModule` services;
|
||||||
|
they cannot inject `AppComponent` services.
|
||||||
|
|
||||||
**_List such providers in the root_ `AppModule` _unless you have a compelling reason to do otherwise_**.
|
Register a service in `AppComponent` providers _only_ if the service must be hidden
|
||||||
|
from components outside the `AppComponent` tree. This is a rare exceptional use case.
|
||||||
|
|
||||||
|
More generally, [prefer registering providers in modules](#q-component-or-module) to registering in components.
|
||||||
|
|
||||||
|
#### **_Discussion_:**
|
||||||
Angular registers all startup module providers with the application root injector.
|
Angular registers all startup module providers with the application root injector.
|
||||||
The services created from root injector providers are available to the entire application.
|
The services created from root injector providers are available to the entire application.
|
||||||
They are _application-scoped_.
|
They are _application-scoped_.
|
||||||
|
@ -439,7 +447,7 @@ a#q-root-component-or-module
|
||||||
Certain services (e.g., the `Router`) only work when registered in the application root injector.
|
Certain services (e.g., the `Router`) only work when registered in the application root injector.
|
||||||
|
|
||||||
By contrast, Angular registers `AppComponent` providers with the `AppComponent`'s own injector.
|
By contrast, Angular registers `AppComponent` providers with the `AppComponent`'s own injector.
|
||||||
`AppComponent`services are available to that component and its component tree.
|
`AppComponent`services are available only to that component and its component tree.
|
||||||
They are _component-scoped_.
|
They are _component-scoped_.
|
||||||
|
|
||||||
The `AppComponent`'s injector is a _child_ of the root injector, one down in the injector hierarchy.
|
The `AppComponent`'s injector is a _child_ of the root injector, one down in the injector hierarchy.
|
||||||
|
@ -448,19 +456,33 @@ a#q-root-component-or-module
|
||||||
|
|
||||||
`AppComponent` services don't exist at the root level where routing operates.
|
`AppComponent` services don't exist at the root level where routing operates.
|
||||||
Lazy loaded modules can't reach them.
|
Lazy loaded modules can't reach them.
|
||||||
In this sample applications, if we had registered `UserService` in the `AppComponent`,
|
In the Angular Module Chapter sample applications, if we had registered `UserService` in the `AppComponent`,
|
||||||
the `HeroComponent` couldn't inject it.
|
the `HeroComponent` couldn't inject it.
|
||||||
The application would fail the moment a user navigated to "Heroes".
|
The application would fail the moment a user navigated to "Heroes".
|
||||||
|
|
||||||
We _can_ register a service in `AppComponent` providers if the app doesn't use routing.
|
.l-hr
|
||||||
We _should_ register a service in `AppComponent` providers if the service must be hidden
|
|
||||||
from components outside the `AppComponent` tree.
|
a#q-component-or-module
|
||||||
|
.l-main-section
|
||||||
|
:marked
|
||||||
|
### Should I add other providers to a module or a component?
|
||||||
|
|
||||||
|
In general, prefer registering feature-specific providers in modules (`@NgModule.providers`)
|
||||||
|
to registering in components (`@Component.providers`).
|
||||||
|
|
||||||
These are special cases.
|
Register a provider with a component when you _must_ limit the scope of a service instance
|
||||||
When in doubt, register with the `AppModule`.
|
to that component and its component tree.
|
||||||
|
Apply the same reasoning to registering a provider with a directive.
|
||||||
|
|
||||||
|
For example, a hero editing component that needs a private copy of a caching hero service should register
|
||||||
|
the `HeroService` with the `HeroEditorComponent`.
|
||||||
|
Then each new instance of the `HeroEditorComponent` gets its own cached service instance.
|
||||||
|
The changes that editor makes to heroes in its service do not touch the hero instances elsewhere in the application.
|
||||||
|
|
||||||
|
[Always register _application-wide_ services with the root `AppModule`](q-root-component-or-module),
|
||||||
|
not the root `AppComponent`.
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#q-why-bad
|
a#q-why-bad
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
Loading…
Reference in New Issue