NgModule
помогает организовать компоненты, директивы и сервисы в логический блок, который подразумевает под собой определенный раздел сайта.
Приложения среднего или большого размера включают в себя разные разделы. Админка, панель управления, заказы, магазин, настройки. Для каждого раздела мы создаем новый NgModule
.
Когда мы импортируем сервис в lazy loaded модуль, то Angular создает новый экземпляр этого сервиса.
RouterModule объявляет и экспортирует директивы (router-outlet
, routerLink
, routerLinkActive
и т.д.) и сервисы (Router
, ActivatedRoute
и т.д.). Для того, чтобы избежать дублирования экземпляров сервиса у RouterModule
есть два метода: forRoot
and forChild
.
Из названий методов ясно, что метод forRoot
должен быть вызван только в корневом модуле (app.module), а forChild
должен вызываться в других (feature) модулях. Таким образом все директивы, компоненты и пайпы всё также будут экспортироваться из модуля, но новый экземпляр сервиса не будет создан.
ProvidedIn
указывает на модуль, в котором будет использоваться сервис. Если указать providedIn: 'root'
то сервис можно использовать по всему приложению.
В Shared модуль я бы поместил директивы, пайпы, компоненты, которые используются по всему приложению и экспортировал бы их из этого модуля. Shared модуль можно импортировать туда, где нам нужны эти компоненты/пайпы/директивы и, таким образом, нам не нужно будет импортировать всё по отдельности.
В Shared модуль я бы не поместил сервисы, которые могут быть импортированы в lazy loaded модуль. Когда lazy loaded модуль импортирует модуль, в котором есть сервис, angular создает новый экземпляр этого сервиса.
Я бы создал Core модуль и поместил бы все использующиеся по всему приложению сервисы. Я бы импортировал этот модуль в app.module, чтобы все модули, даже lazy loaded, использовали один и тот же экземпляр сервиса.
Для того чтобы компоненты/пайпы/директивы из этого модуля были доступны в тех модулях, куда импортирован этот модуль.
Когда роутер лениво загружает модуль, он создает дочерний инжектор и регистрирует сервис в этом дочернем инжекторе. Дочерний инжектор - это уже отдельный инжектор, отличный от root инжектора.
Когда Angular создает lazy компонент для этого модуля и инжектирует сервис, он находит провайдер сервиса в дочернем инжекторе и создает новый экземпляр сервиса. Это будет совершенно другой сервис, который отличается от того, который используется в других частях приложения.
По такому сценарию приложение каждый раз будет создавать новый экземпляр сервиса, вместо того, что бы пользоваться одним.
Источники: