Qual è lo scopo di Fornito con il decoratore iniettabile durante la generazione di servizi in Angular 6?


136

Quando si generano servizi nell'interfaccia della riga di comando angolare, si aggiungono metadati extra con una proprietà "fornita in" con un valore predefinito di "root" per il decoratore iniettabile.

@Injectable({
  providedIn: 'root',
})

Cosa fa esattamente fatto In? Suppongo che questo stia rendendo il servizio disponibile come un servizio singleton di tipo "globale" per l'intera applicazione, tuttavia, non sarebbe più pulito dichiarare tali servizi nell'array provider dell'AppModule?

AGGIORNARE:

Per chiunque altro, il paragrafo seguente ha fornito anche un'altra buona spiegazione, in particolare se si desidera fornire il proprio servizio a un solo modulo funzionale.

Ora esiste un nuovo modo consigliato per registrare un provider, direttamente all'interno del @Injectable()decoratore, usando il nuovo providedIn attributo. Accetta 'root'come valore o qualsiasi modulo dell'applicazione. Quando lo usi 'root', injectableverrai registrato come singleton nell'applicazione e non dovrai aggiungerlo ai provider del modulo root. Allo stesso modo, se lo usi providedIn: UsersModule, il injectableè registrato come fornitore del UsersModulesenza aggiungerlo al providersmodulo. "- https://blog.ninja-squad.com/2018/05/04/what-is-new-angular -6 /

AGGIORNAMENTO 2:

Dopo ulteriori indagini, ho deciso che è utile solo avere providedIn: 'root'

Se si desidera provideun servizio in qualsiasi modulo diverso dal modulo radice, allora è meglio usare l' providersarray nei decoratori del modulo funzione, altrimenti si sarà afflitti da dipendenze circolari. Discussioni interessanti che si terranno qui - https://github.com/angular/angular-cli/issues/10170


17
Penso che i tuoi aggiornamenti dovrebbero essere una risposta (puoi rispondere alle tue domande) invece di aggiungerlo alla tua domanda.
PhoneixS

La parte più importante è SINGLETON, nessuno lo menziona!
Kyle Burkett,

Risposte:


54

se si utilizza fornitoIn, il iniettabile è registrato come fornitore del modulo senza aggiungerlo ai fornitori del modulo.

A partire dal Docs

Il servizio stesso è una classe generata dalla CLI e decorata con @Injectable. Per impostazione predefinita, questo decoratore è configurato con una proprietà fornitaIn, che crea un provider per il servizio. In questo caso, fornisceIn: 'root' specifica che il servizio deve essere fornito nell'iniettore di root.


4
Grazie Sajeetharan. Va bene, quindi sembra che sia un nuovo modo scorciatoia per specificare dove dovrebbe essere fornito il servizio. Immagino che la mia preferenza iniziale sarebbe stata guardare l'elenco dei fornitori di un modulo per vedere tutti i servizi che sono dichiarati come fornitori, piuttosto che esaminare la base di codici sparsi per i tag ProvidedIn .... (?)
Stefan Zvonar,

2
C'era qualche ragione per Angular di aggiungere questo? C'è un problema che sta risolvendo? Non vedo che ci sia una ragione per questo.
prolink007,

3
Mantiene la definizione AppModule / CoreModule un po 'più piccola;)
Stefan Zvonar,

22
@ prolink007. L'uso di fornisceIn consente di caricare i servizi dall'app in modo pigro. Per verificarlo, inserisci i log della console nei tuoi servizi. La mia home page caricava 16 servizi, ora carica 9. È difficile quantificare le prestazioni, ma mi sento meglio sapendo che non sto caricando i servizi fino a quando non sono necessari :).
Stevethemacguy,

3
È possibile rendere agitabili i propri servizi utilizzando l' providedInattributo per definire il punto in cui il servizio deve essere inizializzato quando si utilizza il @Injectable()decoratore. Quindi dovresti rimuoverlo dall'attributo provider della tua NgModuledichiarazione e dalla sua dichiarazione di importazione. Ciò può aiutare a ridurre la dimensione del bundle rimuovendo il codice inutilizzato dal bundle.
nircraft

48

providedIn: 'root' è il modo più semplice ed efficiente per fornire servizi da Angular 6:

  1. Il servizio sarà disponibile a livello di applicazione come singleton senza la necessità di aggiungerlo all'array dei provider di un modulo (come Angular <= 5).
  2. Se il servizio viene utilizzato solo all'interno di un modulo caricato in modo pigro, verrà caricato in modo lento con quel modulo
  3. Se non viene mai utilizzato, non sarà contenuto nella build (albero agitato).

Per ulteriori informazioni prendere in considerazione la lettura della documentazione e delle FAQ di NgModule

btw:

  1. Se non si desidera un singleton a livello di applicazione, utilizzare invece l'array del provider di un componente.
  2. Se vuoi limitare l'ambito in modo che nessun altro sviluppatore possa mai usare il tuo servizio al di fuori di un modulo particolare, usa invece l' providersarray di NgModule.

37

Dai documenti

Che cos'è il decoratore iniettabile?

Contrassegna una classe come disponibile per Injector per la creazione.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

Il servizio stesso è una classe generata dalla CLI e decorata con @Injectable ().

Cosa fa esattamente fatto In?

Determina quali iniettori forniranno il iniettabile, associandolo a un @NgModule o altro InjectorType o specificando che questo iniettabile dovrebbe essere fornito nell'iniettore 'root', che sarà l'iniettore a livello di applicazione nella maggior parte delle app.

providedIn: Type<any> | 'root' | null

fornitaIn: 'root'

Quando si fornisce il servizio a livello di root, Angular crea una singola istanza di servizio condivisa e lo inietta in qualsiasi classe che lo richieda. La registrazione del provider nei metadati @Injectable () consente inoltre ad Angular di ottimizzare un'app rimuovendo il servizio dall'app compilata se non viene utilizzata.

fornitaIn: Modulo

È anche possibile specificare che un servizio deve essere fornito in un particolare @NgModule. Ad esempio, se non si desidera che un servizio sia disponibile per le applicazioni a meno che non importino un modulo creato, è possibile specificare che il servizio deve essere fornito nel modulo

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

Questo metodo è preferito perché abilita Tree-shaking ( Tree shaking è una fase di un processo di generazione che rimuove il codice inutilizzato da una base di codice ) del servizio se nulla lo inietta.

Se non è possibile specificare nel servizio quale modulo dovrebbe fornirlo, è anche possibile dichiarare un fornitore per il servizio all'interno del modulo:

import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}

4
La migliore spiegazione
NOP

2
questa risposta è più migliore della definizione in doc angolare. molto chiaro.
Shameera Anuranga,

2
Molto ben spiegato, grazie mille!
Zaki Mohammed,

Che dire di quando è vuoto, come @Injectable()?
Ben Taliadoros, il

13

fornitaIn indica ad Angular che l'iniettore di root è responsabile della creazione di un'istanza del servizio. I servizi forniti in questo modo vengono automaticamente resi disponibili per l'intera applicazione e non devono essere elencati in alcun modulo.

Le classi di servizio possono fungere da fornitori propri, motivo per cui definirle nel decoratore @Injectable è tutta la registrazione di cui hai bisogno.


4

Secondo il Documentation:

La registrazione del provider nei metadati @Injectable () consente inoltre ad Angular di ottimizzare un'app rimuovendo il servizio dall'app compilata se non viene utilizzata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.