267 votes

Quel est le but de providedIn avec le décorateur Injectable lors de la génération de services dans Angular 6 ?

Lors de la génération de services dans le CLI d'Angular, des métadonnées supplémentaires sont ajoutées avec une propriété "provided in" dont la valeur par défaut est "Root" pour le décorateur Injectable.

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

Que fait exactement providedIn ? Je suppose qu'il s'agit de rendre le service disponible comme un service singleton de type 'global' pour l'ensemble de l'application, cependant, ne serait-il pas plus propre de déclarer de tels services dans le tableau des fournisseurs de l'AppModule ?

UPDATE :

Pour tous les autres, le paragraphe suivant en fournit une autre bonne explication, notamment si vous souhaitez fournir votre service à un module de fonctionnalités uniquement.

Il existe désormais une nouvelle façon, recommandée, d'enregistrer un fournisseur, directement dans le @Injectable() en utilisant le nouveau décorateur providedIn attribut. Il accepte 'root' comme valeur ou tout module de votre application. Lorsque vous utilisez 'root' , votre injectable sera enregistré en tant que singleton dans l'application, et vous n'avez pas besoin de l'ajouter aux fournisseurs du module Root. De même, si vous utilisez providedIn: UsersModule le injectable est enregistré en tant que fournisseur du UsersModule sans l'ajouter à la providers de le module." - https://blog.ninja-squad.com/2018/05/04/what-is-new-angular-6/

UPDATE 2 :

Après une enquête plus approfondie, j'ai décidé qu'il est seulement utile d'avoir providedIn: 'root'

Si vous voulez provide un service dans un module autre que le module Root, il est préférable d'utiliser le module providers dans les décorateurs du module de fonctionnalité, sinon vous serez en proie à des dépendances circulaires. Des discussions intéressantes peuvent avoir lieu ici - https://github.com/angular/angular-cli/issues/10170

27 votes

Je pense que vos mises à jour devraient être une réponse (vous pouvez répondre à vos propres questions) au lieu de les ajouter à votre question.

4 votes

La partie la plus importante est SINGLETON, personne n'en parle !

156voto

Mick Points 1717

providedIn: 'root' est le moyen le plus simple et le plus efficace de fournir des services depuis Angular 6 :

  1. Le service sera disponible dans toute l'application en tant que singleton, sans qu'il soit nécessaire de l'ajouter au tableau des fournisseurs d'un module (comme dans Angular <= 5).
  2. Si le service n'est utilisé que dans un module chargé paresseusement, il sera chargé paresseusement avec ce module.
  3. S'il n'est jamais utilisé, il ne sera pas contenu dans la construction (arbre secoué).

Pour plus d'informations, vous pouvez lire le documentation y FAQ sur les NgModules

Au fait :

  1. Si vous ne voulez pas d'un singleton pour l'ensemble de l'application, utilisez le tableau du fournisseur d'un composant à la place.
  2. Si vous souhaitez limiter le champ d'application afin qu'aucun autre développeur ne puisse utiliser votre service en dehors d'un module particulier, utilisez l'option providers de NgModule à la place.

1 votes

Simple, stellaire et direct !

0 votes

Question ! Mon service va très certainement dépendre d'autres services (via DI dans son constructeur). Avant, toutes les dépendances étaient gérées dans le module fournissant le service... Qu'en est-il maintenant ? Surtout s'il dépend d'une bibliothèque tierce (n'utilisant pas providedIn : Root), comment allons-nous faire ?

1 votes

Je ne pense pas du tout que cette réponse soit exacte actuellement. La documentation indique que providedIn: UserModule est une méthode qui "permet de secouer les arbres", ce qui implique providedIn: "root" ne permet pas de secouer les arbres. De plus, la documentation de providedIn: "any" Notez que c'est la façon dont les modules chargés paresseusement peuvent effectivement charger paresseusement le service, tout en créant leur propre instance indépendante de celui-ci.

117voto

Nips Points 772

De Docs

Qu'est-ce qu'un décorateur injectable ?

Marque une classe comme disponible pour l'injecteur pour la création.

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

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

Le service lui-même est une classe que le CLI a générée et qui est décorée avec @Injectable().

Que fait exactement providedIn ?

Détermine les injecteurs qui fourniront l'injectable, soit en l'associant à un @NgModule ou à un autre InjectorType, soit en spécifiant que cet injectable doit être fourni dans l'injecteur 'Root', qui sera l'injecteur de niveau application dans la plupart des applications.

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

providedIn : 'Root' (racine)

Lorsque vous fournissez le service au niveau de la racine, Angular crée une instance unique et partagée du service et l'injecte dans toute classe qui le demande. L'enregistrement du fournisseur dans les métadonnées @Injectable() permet également à Angular d'optimiser une application en supprimant le service de l'application compilée s'il n'est pas utilisé.

fourni dans : Module

Il est également possible de spécifier qu'un service doit être fourni dans un @NgModule particulier. Par exemple, si vous ne voulez pas qu'un service soit disponible pour les applications à moins qu'elles importent un module que vous avez créé, vous pouvez spécifier que le service doit être fourni dans le module

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

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

Cette méthode est préférée car elle permet le Tree-shaking ( Secouer les arbres est une étape d'un processus de construction qui supprime le code inutilisé d'une base de code. ) du service si rien ne l'injecte.

S'il n'est pas possible de préciser dans le service quel module doit le fournir, vous pouvez également déclarer un fournisseur pour le service au sein du module :

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

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

14 votes

La meilleure explication.

4 votes

Cette réponse est bien meilleure que la définition dans la doc angulaire. très clair.

2 votes

Très bien expliqué, merci beaucoup !

72voto

Sajeetharan Points 108195

Si vous utilisez providedIn, l'injectable est enregistré comme fournisseur du module sans l'ajouter aux fournisseurs du module.

De Docs

Le service lui-même est une classe que le CLI a générée et qui est décorée avec @Injectable. Par défaut, ce décorateur est configuré avec une propriété providedIn, qui crée un fournisseur pour le service. Dans ce cas, la propriété providedIn : 'Root' indique que le service doit être fourni dans l'injecteur Root.

4 votes

Merci Sajeetharan. Ok, donc il semble que ce soit un nouveau raccourci pour spécifier où le service doit être fourni. Je suppose que ma préférence initiale aurait été de regarder la liste des fournisseurs d'un module pour voir tous les services qui sont déclarés comme fournisseurs, plutôt que de parcourir la base de code éparpillée pour trouver les balises ProvidedIn ..... ( ?)

3 votes

Y avait-il une raison pour qu'Angular ajoute cela ? Y a-t-il un problème que cela résout ? Je ne vois pas de raison à cela.

4 votes

La définition de AppModule / CoreModule reste un peu plus petite ;)

18voto

Jawad Farooqi Points 104

ProvidedIn indique à Angular que l'injecteur Root est chargé de créer une instance de votre service. Les services qui sont fournis de cette manière sont automatiquement mis à la disposition de l'ensemble de l'application et n'ont pas besoin d'être répertoriés dans un module.

Les classes de service peuvent agir comme leurs propres fournisseurs, c'est pourquoi les définir dans le décorateur @Injectable est tout l'enregistrement dont vous avez besoin.

4voto

Maarti Points 1715

Selon le Documentation :

L'enregistrement du fournisseur dans les métadonnées @Injectable() permet également à Angular d'optimiser une application en supprimant le service de l'application compilée s'il ne compilée s'il n'est pas utilisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X