Dans le composant Angular2, la configuration providers
est l'une des clés que nous pourrions spécifier. Comment ces prestataires sont-ils définis et à quoi servent-ils?
@Component({
..
providers: [..],
..
})
Note:
La documentation angulaire2 mûrit progressivement mais reste rare. Il définit actuellement fournisseurs comme:
Un ensemble de fournisseurs d'injection de dépendance pour les services requis par le composant.
Cette définition récursive n'est pas très utile. Une explication plus détaillée avec un exemple serait vraiment utile.
Les fournisseurs sont généralement des objets singleton (une instance), auxquels d'autres objets ont accès via l'injection de dépendance (DI).
Si vous prévoyez d'utiliser un objet plusieurs fois, par exemple Http
service dans différents composants, vous pouvez demander la même instance de ce service (le réutiliser). Vous le faites à l’aide de DI en fournissant une référence au même objet que DI crée pour vous.
@Component){
..
providers: [Http]
}
.. au lieu de créer un nouvel objet à chaque fois:
@Component){}
class Cmp {
constructor() {
// this is pseudo code, doens't work
this.http = new Http(...options);
}
}
C’est une approximation, mais c’est l’idée générale derrière Dependency Injection - laissez le cadre gérer la création et la maintenance des objets réutilisables ... Provider est le terme utilisé par Angular pour désigner ces objets réutilisables. objets (dépendances).
Enregistrez les produits injectables
Les prestataires font connaître les injectables aux DI d'Angular et définissent la portée d'un injectable (service).
Hiérarchie des injecteurs
Angular's DI crée une arborescence d'injecteurs (parent> enfant> petit-enfant> ...) qui ressemble à la structure de vos composants et directives.
Instance unique par fournisseur
Les prestataires sont maintenus par injecteur. Chaque fournisseur fournit une seule instance d'un injectable.
Recherche du fournisseur
Lorsqu'un composant ou une directive a une dépendance (paramètre constructeur), DI commence à rechercher l'injecteur de ce composant pour les fournisseurs. S'il en a un, il demande l'instance à ce fournisseur et l'injecte.
Si l'injecteur n'a pas de fournisseur pour la clé demandée (type), l'injecteur parent est visité jusqu'à la racine (bootstrap) jusqu'à ce qu'un fournisseur soit trouvé et que son instance puisse être injectée. (Si aucun fournisseur n'est trouvé, DI génère une erreur).
Définit la portée d'une instance injectable
De cette façon, vous pouvez définir la portée d'un service partagé, car DI commence à rechercher à partir du composant où une instance est demandée vers le haut jusqu'à ce qu'elle en trouve une.
Singleton ou non
Le nombre d'emplacements que vous fournissez à un injectable détermine le nombre d'instances qui seront créées (elles ne sont instanciées que si elles sont réellement demandées).
Si vous voulez une seule instance pour l’ensemble de votre application, fournissez un seul injectable une fois au niveau du composant racine (ou avec bootstrap(AppComponent, [...])
qui entraîne le même comportement.
Si vous souhaitez une nouvelle instance pour chaque composant A
, ajoutez-la aux fournisseurs du composant A
.
(update) NgModule paresseux et non paresseux
Avec l'introduction de NgModule
modules, des niveaux supplémentaires ont été introduits. Les fournisseurs enregistrés avec des modules non chargés paresseux sont au-dessus du composant racine dans la hiérarchie.
Les modules chargés paresseux sont au-dessus des composants et des directives chargées par ces composants.
Les fournisseurs étant en lecture seule après la création d'un injecteur, il est impossible d'ajouter des fournisseurs de modules chargés paresseux à l'injecteur racine. Par conséquent, les modules chargés paresseux ont leur propre domaine racine.
Voir aussi https://stackoverflow.com/a/45231440/217408
Pensez aux fournisseurs comme une recette qui indique à angular comment injecter un service.
Nous déclarons souvent les fournisseurs dans angular de cette façon:
providers: [AnyService]
Ceci est juste un coup de main pour cela:
[new Provider(AnyService, {useClass: AnyService})]
Les deux approches disent: Chaque fois que quelqu'un requiert "AnyService", fournissez la classe "AnyService".
Voir que même si je fournis la même classe dans l'exemple ci-dessus, dans un autre scénario, je pourrais faire quelque chose comme ceci.
[new Provider(AnyService, {useClass: AnyServiceCustom})]
Mais dans les deux scénarios, constructeur resterait le même:
constructor( private _anyService: AnyService) {
}
Pour mieux le comprendre, vous devez comprendre le fonctionnement de l'injection de dépendance dans Angular 2, car les prestataires y sont directement liés.
Ceci est une lecture indispensable pour chaque développeur angular 2.
Ajouter des mots @Sasxa, je veux pointer vers Pro Angular livre par Adam Freeman (chapitre 20 (Utilisation des fournisseurs de services))) pour une meilleure, explication claire et détaillée avec exemples.
Les fournisseurs sont des classes qui créent et gèrent objets de service la première fois que Angular doit résoudre une dépendance. Les fournisseurs sont utilisés pour enregistrer les classes dans un module angular en tant que service . Et ensuite, ces classes de service peuvent être utilisées par d'autres composants pendant la phase de création de celui-ci dans le module.
" Services sont des objets offrant des fonctionnalités communes permettant de prendre en charge d'autres blocs de construction d'une application, tels que des directives, des composants et des canaux. Ce qui est important à propos des services, c'est la façon dont ils sont utilisés, un processus appelé injection de dépendance . L'utilisation de services peut augmenter la flexibilité et l'évolutivité d'une application Angular, mais l'injection de dépendance peut être un sujet difficile à comprendre. "(Pro Angular (chapitre 20))
En réalité, les services peuvent gérer la distribution d'objets en tant que services utilisant l'injection de dépendance.
import { Injectable } from "@angular/core";
export enum LogLevel {DEBUG, INFO, ERROR}
@Injectable()
export class LogService {
minimumLevel: LogLevel = LogLevel.INFO;
logInfoMessage(message: string){
this.logMessage(LogLevel.INFO, message);
}
}
@Component({
selector: "example",
templateUrl: "example.component.html"
})
export class exampleComponent {
constructor(logService: LogService) {};
//to do impl
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],
providers: [ LogService ],
declarations: [ ExampleComponent],
bootstrap: [ AppComponent ]
})
export class AppModule { }