It's standard practice for feature modules with routing components to define their own routes.
You'll get to [`ContactRoutingModule`](#contact-routing-module) in a moment.
The remaining two routes use lazy loading syntax to tell the router where to find the modules for the hero and crisis features:
A lazy-loaded NgModule location is a _string_, not a _type_.
In this app, the string identifies both the NgModule _file_ and the NgModule _class_,
the latter separated from the former by a `#`.
### Routing module imports
A _routing module_ typically imports the Angular `RouterModule` so it can register routes.
It may also import a _feature module_ which registers routes (either directly or through its companion _routing module_).
This `AppRoutingModule` does both.
Call `RouterModule.forRoot` exactly once for the entire app.
Calling it in the `AppRoutingModule`, the companion to the root `AppModule`,
is a good way to ensure that this method is called exactly once.
Never call `RouterModule.forRoot` in a feature's _routing module_.
### Re-export _RouterModule_
All _routing modules_ should re-export the `RouterModule`.
Always call `RouterModule.forChild` in a feature-routing module.
Never call `RouterModule.forRoot`.
#### _ContactModule_ changes
Because the app navigates to the `ContactComponent` instead of
simply displaying it in the `AppComponent` template,
the `ContactModule` has changed.
* It imports the `ContactRoutingModule`.
* It no longer exports `ContactComponent`.
The `ContactComponent` is only displayed by the router,
No template references its `` selector.
There's no reason to make it public via the `exports` array.
Here is the latest version, side-by-side with the previous version.
{@a hero-module}
### Lazy-loaded routing
The `HeroModule` and `CrisisModule` have corresponding _routing modules_, `HeroRoutingModule` and `CrisisRoutingModule`.
The app _lazy loads_ the `HeroModule` and the `CrisisModule`.
That means the `HeroModule` and the `CrisisModule` are not loaded into the browser until the user navigates to their components.
Do not import the `HeroModule` or `CrisisModule` or any of their classes outside of their respective file folders.
If you do, you will unintentionally load those modules and all of their code
when the application starts, defeating the purpose of lazy loading.
For example, if you import the `HeroService` in `AppModule`,
the `HeroService` class and all related hero classes will be loaded when the application starts.
Lazy loading can improve the app's perceived performance because the browser doesn't have to process lazy-loaded code when the app starts.
It may _never_ process that code.
You cannot tell that these modules are lazy-loaded by looking at their _routing modules_.
They happen to be a little more complex than `ContactRoutingModule`.
For example, The `HeroRoutingModule` has [child routes](guide/router#child-routing-component).
But the added complexity springs from intrinsic hero and crisis functionality, not from lazy loading.
Fundamentally, these _routing modules_ are just like `ContactRoutingModule` and you write them the same way.
{@a lazy-load-DI}
### Lazy-loaded NgModule providers
There is a **runtime difference** that can be significant.
Services provided by lazy-loaded NgModules are only available to classes instantiated within the lazy-loaded context. The reason has to do with dependency injection.
When an NgModule is _eagerly loaded_ as the application starts,
its providers are added to the application's _root injector_.
Any class in the application can inject a service from the _root injector_.
When the router _lazy loads_ an NgModule, Angular instantiates the module
with a _child injector_ (a descendant of the _root injector_)
and adds the module's providers to this _child injector_.
Classes created with the _child injector_ can inject one of its provided services.
Classes created with _root injector_ cannot.
Each of the three feature modules has its own data access service.
Because the `ContactModule` is _eagerly loaded_ when the application starts,
its `ContactService` is provided by the application's _root dependency injector_.
That means the `ContactService` can be injected into any application class, including hero and crisis components.
Because `CrisisModule` is _lazy-loaded_,
its `CrisisService` is provided by the `CrisisModule` _child injector_.
It can only be injected into one of the crisis components.
No other kind of component can inject the `CrisisService` because no other kind of component can be reached along a route that lazy loads the `CrisisModule`.
### Lazy-loaded NgModule lifetime
Both eager and lazy-loaded NgModules are created _once_ and never destroyed.
This means that their provided service instances are created _once_ and never destroyed.
As you navigate among the application components, the router creates and destroys instances of the contact, hero, and crisis components.
When these components inject data services provided by their modules,
they get the same data service instance each time.
If the `HeroService` kept a cache of unsaved changes and the user navigated to the `ContactComponent` or the `CrisisListComponent`, the pending hero changes would remain in the one `HeroService` instance, waiting to be saved.
But if you provided the `HeroService` in the `HeroComponent` instead of the `HeroModule`, new `HeroService` instances would be created each time
the user navigated to a hero component. Previously pending hero changes would be lost.
To illustrate this point, the sample app provides the `HeroService` in the `HeroComponent` rather than the `HeroModule`.
Run the app, open the browser development tools, and look at the console as you navigate among the feature pages.
// App starts
ContactService instance created.
...
// Navigate to Crisis Center
CrisisService instance created.
...
// Navigate to Heroes
HeroService instance created.
...
// Navigate to Contact
HeroService instance destroyed.
...
// Navigate back to Heroes
HeroService instance created.
The console log shows the `HeroService` repeatedly created and destroyed.
The `ContactService` and `CrisisService` are created but never destroyed, no matter where you navigate.
#### Run it
Try this routed version of the sample.
Try the live example.
{@a shared-module}
## Shared modules
The app is shaping up.
But there are a few annoying problems.
There are three unnecessarily different _highlight directives_
and the many files cluttering the app folder level could be better organized.
You can eliminate the duplication and tidy-up by writing a `SharedModule`
to hold the common components, directives, and pipes.
Then share this NgModule with the other NgModules that need these declarables.
Use the CLI to create the `SharedModule` class in its `src/app/shared` folder.
ng generate module shared
Now refactor as follows:
- Move the `AwesomePipe` from `src/app/contact` to `src/app/shared`.
- Move the `HighlightDirective` from `src/app/hero` to `src/app/shared`.
- Delete the _highlight directive_ classes from `src/app/` and `src/app/contact`.
- Update the `SharedModule` as follows:
Note the following:
* It declares and exports the shared pipe and directive.
* It imports and re-exports the `CommonModule` and `FormsModule`
* It can re-export `FormsModule` without importing it.
### Re-exporting NgModules
Technically, there is no need for `SharedModule` to import `CommonModule` or `FormsModule`.
`SharedModule` doesn't declare anything that needs material from `CommonModule` or `FormsModule`.
But NgModules that would like to import `SharedModule` for its pipe and highlight directive happen also to declare components that need `NgIf` and `NgFor` from `CommonModule`
and do two-way binding with `[(ngModel)]` from the `FormsModule`.
Normally, they'd have to import `CommonModule` and `FormsModule` as well as `SharedModule`.
Now they can just import `SharedModule`.
By exporting `CommonModule` and `FormsModule`,
`SharedModule` makes them available to its importers _for free_.
#### A trimmer _ContactModule_
See how `ContactModule` became more concise, compared to its previous version:
Notice the following:
* The `AwesomePipe` and `ContactHighlightDirective` are gone.
* The imports include `SharedModule` instead of `CommonModule` and `FormsModule`.
* The new version is leaner and cleaner.
### Why _TitleComponent_ isn't shared
`SharedModule` exists to make commonly used components, directives, and pipes available
for use in the templates of components in many other NgModules.
The `TitleComponent` is used only once by the `AppComponent`.
There's no point in sharing it.
{@a no-shared-module-providers}
### Why _UserService_ isn't shared
While many components share the same service instances,
they rely on Angular dependency injection to do this kind of sharing, not the NgModule system.
Several components of the sample inject the `UserService`.
There should be only one instance of the `UserService` in the entire application
and only one provider of it.
`UserService` is an application-wide singleton.
You don't want each NgModule to have its own separate instance.
Yet there is [a real danger](guide/ngmodule-faq#q-why-bad) of that happening
if the `SharedModule` provides the `UserService`.
Do *not* specify app-wide singleton `providers` in a shared module.
A lazy-loaded NgModule that imports that shared module makes its own copy of the service.
{@a core-module}
## The Core module
At the moment, the root folder is cluttered with the `UserService`
and `TitleComponent` that only appear in the root `AppComponent`.
You didn't include them in the `SharedModule` for reasons just explained.
Instead, gather them in a single `CoreModule` that you import once when the app starts
and never import anywhere else.
Perform the following steps:
1. Create a `CoreModule` class in an `src/app/core` folder.
1. Move the `TitleComponent` and `UserService` from `src/app/` to `src/app/core`.
1. Declare and export the `TitleComponent`.
1. Provide the `UserService`.
1. Update the root `AppModule` to import `CoreModule`.
Most of this work is familiar. The interesting part is the `CoreModule`.
You're importing some extra symbols from the Angular core library that you're not using yet.
They'll become relevant later in this page.
The `@NgModule` metadata should be familiar.
You declare the `TitleComponent` because this NgModule owns it.
You export it because `AppComponent` (which is in `AppModule`) displays the title in its template.
`TitleComponent` needs the Angular `NgIf` directive that you import from `CommonModule`.
`CoreModule` provides the `UserService`. Angular registers that provider with the app root injector,
making a singleton instance of the `UserService` available to any component that needs it,
whether that component is eagerly or lazily loaded.
Why bother?
This scenario is clearly contrived.
The app is too small to worry about a single service file and a tiny, one-time component.
A `TitleComponent` sitting in the root folder isn't bothering anyone.
The root `AppModule` can register the `UserService` itself,
as it does currently, even if you decide to relocate the `UserService` file to the `src/app/core` folder.
Real-world apps have more to worry about.
They can have several single-use components (such as spinners, message toasts, and modal dialogs)
that appear only in the `AppComponent` template.
You don't import them elsewhere so they're not shared in that sense.
Yet they're too big and messy to leave loose in the root folder.
Apps often have many singleton services like this sample's `UserService`.
Each must be registered exactly once, in the app root injector, when the application starts.
While many components inject such services in their constructors—and
therefore require JavaScript `import` statements to import their symbols—no
other component or NgModule should define or re-create the services themselves.
Their _providers_ aren't shared.
We recommend collecting such single-use classes and hiding their details inside a `CoreModule`.
A simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole.
#### A trimmer _AppModule_
Here is the updated `AppModule` paired with version 3 for comparison:
`AppModule` now has the following qualities:
* A little smaller because many `src/app/root` classes have moved to other NgModules.
* Stable because you'll add future components and providers to other NgModules, not this one.
* Delegated to imported NgModules rather than doing work.
* Focused on its main task, orchestrating the app as a whole.
{@a core-for-root}
### Configure core services with _CoreModule.forRoot_
An NgModule that adds providers to the application can offer a facility for configuring those providers as well.
By convention, the `forRoot` static method both provides and configures services at the same time.
It takes a service configuration object and returns a
[ModuleWithProviders](api/core/ModuleWithProviders), which is
a simple object with the following properties:
* `ngModule`: the `CoreModule` class
* `providers`: the configured providers
The root `AppModule` imports the `CoreModule` and adds the `providers` to the `AppModule` providers.
More precisely, Angular accumulates all imported providers before appending the items listed in `@NgModule.providers`.
This sequence ensures that whatever you add explicitly to the `AppModule` providers takes precedence
over the providers of imported NgModules.
Add a `CoreModule.forRoot` method that configures the core `UserService`.
You've extended the core `UserService` with an optional, injected `UserServiceConfig`.
If a `UserServiceConfig` exists, the `UserService` sets the user name from that config.
Here's `CoreModule.forRoot` that takes a `UserServiceConfig` object:
Lastly, call it within the `imports` list of the `AppModule`.
The app displays "Miss Marple" as the user instead of the default "Sherlock Holmes".
Call `forRoot` only in the root module, `AppModule`.
Calling it in any other NgModule, particularly in a lazy-loaded NgModule,
is contrary to the intent and can produce a runtime error.
Remember to _import_ the result; don't add it to any other `@NgModule` list.
{@a prevent-reimport}
### Prevent reimport of the _CoreModule_
Only the root `AppModule` should import the `CoreModule`.
[Bad things happen](guide/ngmodule-faq#q-why-bad) if a lazy-loaded NgModule imports it.
You could hope that no developer makes that mistake.
Or you can guard against it and fail fast by adding the following `CoreModule` constructor.
The constructor tells Angular to inject the `CoreModule` into itself.
That seems dangerously circular.
The injection would be circular if Angular looked for `CoreModule` in the _current_ injector.
The `@SkipSelf` decorator means "look for `CoreModule` in an ancestor injector, above me in the injector hierarchy."
If the constructor executes as intended in the `AppModule`,
there is no ancestor injector that could provide an instance of `CoreModule`.
The injector should give up.
By default, the injector throws an error when it can't find a requested provider.
The `@Optional` decorator means not finding the service is OK.
The injector returns `null`, the `parentModule` parameter is null,
and the constructor concludes uneventfully.
It's a different story if you improperly import `CoreModule` into a lazy-loaded NgModule such as `HeroModule` (try it).
Angular creates a lazy-loaded NgModule with its own injector, a _child_ of the root injector.
`@SkipSelf` causes Angular to look for a `CoreModule` in the parent injector, which this time is the root injector.
Of course it finds the instance imported by the root `AppModule`.
Now `parentModule` exists and the constructor throws the error.
## Conclusion
You made it! You can examine and download the complete source for this final version from the live example.
## Frequently asked questions
Now that you understand NgModules, you may be interested
in the companion [NgModule FAQs](guide/ngmodule-faq "NgModule FAQs") page
with its ready answers to specific design and implementation questions.