Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 38bef16

Browse files
authored
docs(ngmodule-faq): stronger, clearer advice on where to register providers (#2262)
1 parent 94a40a1 commit 38bef16

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

public/docs/ts/latest/cookbook/ngmodule-faq.jade

+39-17
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ block includes
3333
* [Can I re-export imported classes and modules?](#q-re-export)
3434
* [What is the _forRoot_ method?](#q-for-root)
3535

36-
Service Providers
36+
Service Providers
3737
* [Why is a service provided in a feature module visible everywhere?](#q-module-provider-visibility)
38-
* [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
38+
* [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
3939
* [What if two modules provide the _same_ service?](#q-module-provider-duplicates)
4040
* [How do I restrict service scope to a module?](#q-component-scoped-providers)
41-
* [Should I add providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
41+
* [Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
42+
* [Should I add other providers to a module or a component?](#q-component-or-module)
4243
* [Why is it bad if _SharedModule_ provides a service to a lazy loaded module?](#q-why-bad)
4344
* [Why does lazy loading create a child injector?](#q-why-child-injector)
4445
* [How can I tell if a module or service was previously loaded?](#q-is-it-loaded)
@@ -424,22 +425,29 @@ a#q-component-scoped-providers
424425
a#q-root-component-or-module
425426
.l-main-section
426427
:marked
427-
### Should I add providers to the root _AppModule_ or the root _AppComponent_?
428+
### Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?
428429

429-
Most apps launch with an initial set of service providers.
430-
Should we register those providers on the root `AppModule` (`@NgModule.providers`) or
431-
the root `AppComponent` (`@Component.providers`)?
430+
.alert.is-helpful
431+
:marked
432+
Register application-wide providers in the root `AppModule`, not in the `AppComponent`.
433+
:marked
434+
Lazy-loaded modules and their components can inject `AppModule` services;
435+
they cannot inject `AppComponent` services.
432436

433-
**_List such providers in the root_ `AppModule` _unless you have a compelling reason to do otherwise_**.
434-
437+
Register a service in `AppComponent` providers _only_ if the service must be hidden
438+
from components outside the `AppComponent` tree. This is a rare exceptional use case.
439+
440+
More generally, [prefer registering providers in modules](#q-component-or-module) to registering in components.
441+
442+
#### **_Discussion_:**
435443
Angular registers all startup module providers with the application root injector.
436444
The services created from root injector providers are available to the entire application.
437445
They are _application-scoped_.
438446

439447
Certain services (e.g., the `Router`) only work when registered in the application root injector.
440448

441449
By contrast, Angular registers `AppComponent` providers with the `AppComponent`'s own injector.
442-
`AppComponent`services are available to that component and its component tree.
450+
`AppComponent`services are available only to that component and its component tree.
443451
They are _component-scoped_.
444452

445453
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
448456

449457
`AppComponent` services don't exist at the root level where routing operates.
450458
Lazy loaded modules can't reach them.
451-
In this sample applications, if we had registered `UserService` in the `AppComponent`,
459+
In the Angular Module Chapter sample applications, if we had registered `UserService` in the `AppComponent`,
452460
the `HeroComponent` couldn't inject it.
453461
The application would fail the moment a user navigated to "Heroes".
454462

455-
We _can_ register a service in `AppComponent` providers if the app doesn't use routing.
456-
We _should_ register a service in `AppComponent` providers if the service must be hidden
457-
from components outside the `AppComponent` tree.
463+
.l-hr
464+
465+
a#q-component-or-module
466+
.l-main-section
467+
:marked
468+
### Should I add other providers to a module or a component?
469+
470+
In general, prefer registering feature-specific providers in modules (`@NgModule.providers`)
471+
to registering in components (`@Component.providers`).
458472

459-
These are special cases.
460-
When in doubt, register with the `AppModule`.
473+
Register a provider with a component when you _must_ limit the scope of a service instance
474+
to that component and its component tree.
475+
Apply the same reasoning to registering a provider with a directive.
476+
477+
For example, a hero editing component that needs a private copy of a caching hero service should register
478+
the `HeroService` with the `HeroEditorComponent`.
479+
Then each new instance of the `HeroEditorComponent` gets its own cached service instance.
480+
The changes that editor makes to heroes in its service do not touch the hero instances elsewhere in the application.
481+
482+
[Always register _application-wide_ services with the root `AppModule`](q-root-component-or-module),
483+
not the root `AppComponent`.
461484

462485
.l-hr
463-
464486
a#q-why-bad
465487
.l-main-section
466488
:marked

0 commit comments

Comments
 (0)