Penso che le risposte siano corrette ma penso che manchi qualcosa.
La cosa che manca è "perché e cosa risolve?".
Ok iniziamo.
Per prima cosa menzioniamo alcune informazioni:
Tutti i moduli hanno accesso ai servizi di root.
Quindi anche i moduli caricati pigri possono utilizzare un servizio fornito in app.module
.
Cosa succederà se un modulo caricato pigro fornirà a se stesso un servizio che il modulo dell'app ha già fornito? ci saranno 2 casi.
Non è un problema ma a volte lo è .
Come possiamo risolvere ? semplicemente non importare un modulo con quel provider in moduli caricati pigri.
Fine della storia.
Questo ^ era solo per mostrare che i moduli caricati in modo pigro hanno il loro punto di iniezione (al contrario dei moduli non caricati in modo pigro).
Ma cosa succede quando un modulo condiviso (!) Ha dichiarato providers
e quel modulo viene importato da lazy e app.module
? Ancora una volta, come abbiamo detto, due casi.
Quindi come possiamo risolvere questo problema nel POV del modulo condiviso? Abbiamo bisogno di un modo da non usare providers:[]
! Perché? perché verranno importati automaticamente sia in consuming lazy che in app.module e non lo vogliamo, poiché abbiamo visto che ognuno avrà un'istanza diversa.
Bene, si scopre che possiamo dichiarare un modulo condiviso che non avrà providers:[]
, ma fornirà comunque provider (scusate :))
Come? Come questo :
Avviso, nessun provider.
Ma
Accesso al meccanismo manuale tramite convenzione:
Noterai che i fornitori nelle immagini hanno service1
eservice2
Questo ci permette di importare service2
moduli caricati in modo pigro e moduli service1
non pigri. ( tosse ... router .... tosse )
A proposito, nessuno ti impedisce di chiamare forRoot
all'interno di un modulo pigro. ma avrai 2 istanze perché app.module
dovresti farlo anche tu, quindi non farlo in moduli pigri.
Inoltre, se app.module
chiama forRoot
(e nessuno chiama forchild
), va bene, ma root injector avrà solo service1
. (disponibile per tutte le app)
Allora perché ne abbiamo bisogno? Direi :
Consente a un modulo condiviso, di essere in grado di dividere i suoi diversi provider da utilizzare con moduli desiderosi e moduli pigri - tramite forRoot
e forChild
convenzione. Ripeto: convenzione
Questo è tutto.
ASPETTARE !! non una sola parola sul singleton ?? quindi perché leggo singleton ovunque?
Ebbene, è nascosto nella frase sopra ^
Consente a un modulo condiviso di essere in grado di dividere i suoi diversi provider da utilizzare con moduli desiderosi e moduli pigri - tramite forRoot e forChild .
La convenzione (!!!) permette che sia singleton - o per essere più precisi - se non seguirai la convenzione - NON otterrai un singleton.
Quindi, se carichi solo forRoot
in app.module
, ottieni solo un'istanza perché dovresti chiamarla forRoot
solo in app.module
.
BTW - a questo punto puoi dimenticarti forChild
. il modulo caricato pigro non dovrebbe / non chiamerà forRoot
, quindi sei al sicuro nel POV di singleton.
forRoot e forChild non sono un pacchetto indistruttibile - è solo che non ha senso chiamare Root che ovviamente verrà caricato solo in app.module
senza dare la possibilità di moduli pigri, avere i propri servizi, senza creare nuovi servizi-che-dovrebbero-essere -singleton.
Questa convenzione ti dà una bella capacità chiamata forChild
- consumare "servizi solo per moduli caricati in modo pigro".
Ecco una demo I fornitori di root producono numeri positivi, i moduli caricati pigri producono numeri negativi.