Creo que las respuestas son correctas, pero creo que falta algo.
Lo que falta es "¿por qué y qué resuelve?".
Vale, empecemos.
Primero mencionemos algo de información:
Todos los módulos tienen acceso a los servicios raíz.
Por lo tanto, incluso los módulos con carga diferida pueden usar un servicio que se proporcionó en app.module
.
¿Qué pasará si un módulo de carga diferida se proporciona a sí mismo un servicio que el módulo de la aplicación ya proporcionó? habrá 2 instancias.
No es un problema, pero a veces lo es .
¿Cómo podemos solucionarlo? simplemente no importe un módulo con ese proveedor a módulos con carga diferida.
Fin de la historia.
Esto ^ fue solo para mostrar que los módulos con carga diferida tienen su propio punto de inyección (a diferencia de los módulos sin carga diferida).
Pero, ¿qué sucede cuando se ha declarado un módulo compartido (!)providers
Y ese módulo es importado por lazy y app.module
? Nuevamente, como dijimos, dos instancias.
Entonces, ¿cómo podemos resolver esto en el módulo compartido POV? ¡Necesitamos una forma de no usar providers:[]
! ¿Por qué? porque se importarán automáticamente tanto a lazy consumidor como a app.module y no queremos eso, ya que vimos que cada una tendrá una instancia diferente.
Bueno, resulta que podemos declarar un módulo compartido que no tendrá providers:[]
, pero aún así, proporcionará proveedores (lo siento :))
¿Cómo? Me gusta esto :
Aviso, no hay proveedores.
Pero
¿Qué pasará ahora cuando app.module importe el módulo compartido con el punto de vista del servicio? NADA.
¿Qué pasará ahora cuando un módulo perezoso importará el módulo compartido con el punto de vista del servicio? NADA.
Ingresando al mecanismo manual a través de la convención:
Notará que los proveedores en las imágenes tienen service1
yservice2
Esto nos permite importar service2
para módulos con carga diferida y módulos service1
no diferidos. ( tos ... enrutador ... tos )
Por cierto, nadie te detiene para llamar forRoot
dentro de un módulo perezoso. pero tendrá 2 instancias porque app.module
también debería hacerlo, así que no lo haga en módulos perezosos.
Además, si app.module
llama forRoot
(y nadie llama forchild
), está bien, pero el inyector raíz solo tendrá service1
. (disponible para todas las aplicaciones)
Entonces, ¿por qué lo necesitamos? Yo diria :
Permite que un módulo compartido, para poder dividir sus diferentes proveedores para ser utilizado con módulos ansiosos y módulos perezosos - vía forRoot
y forChild
convenciones. Repito: convención
Eso es.
ESPERE !! ni una sola palabra sobre singleton? entonces, ¿por qué leo singleton en todas partes?
Bueno, está escondido en la oración anterior ^
Permite que un módulo compartido pueda dividir sus diferentes proveedores para usar con módulos ansiosos y módulos perezosos, a través de forRoot y forChild .
La convención (!!!) permite que sea singleton, o para ser más preciso, si no sigue la convención, NO obtendrá un singleton.
Entonces, si solo carga forRoot
en el app.module
, entonces obtiene solo una instancia porque solo debe llamarlo forRoot
en el app.module
.
Por cierto, en este punto puedes olvidarte forChild
. el módulo de carga diferida no debería / no llamará forRoot
, por lo que está seguro en POV de singleton.
forRoot y forChild no son un paquete irrompible, es solo que no tiene sentido llamar a Root, que obviamente se cargará solo app.module
sin dar la capacidad a los módulos perezosos, tener sus propios servicios, sin crear nuevos servicios, que deberían ser -único.
Esta convención le da una buena habilidad llamada forChild
- consumir "servicios sólo para módulos cargados de forma diferida".
Aquí hay una demostración Los proveedores raíz producen números positivos, los módulos cargados de forma diferida producen números negativos.