L’injection de dépendances Angular

Nous allons parler dans cet article d'un des piliers du framework Angular : L'injection de dépendance. L'injection de dépendance est une notion importante à bien comprendre et à bien implémenter. Déjà présent dans AngularJS, cette notion est toujours présente dans le nouveau framework de Google mais à bien changé. Nous allons prendre l'exemple d'un service de Log pour illustrer nos propos. Un service est une class avec un décorateur spécifique @Injectable().  

Le décorateur @Injectable()

@Injectable() est un décorateur un peu particulier. Il ne permet pas l’injection à proprement parlé, mais plutôt d’initialiser un contexte détectabilité. Si vous injectez dans un de vos services ( sans ce décorateur) un autre service, le moteur d'injection retournera une erreur. Angular conseille de toujours mettre cette annotation sur un service même si vous n'utilisez pas les injections dans les premiers développements de votre service afin d'éviter de se poser la question plus tard.

Pour informaion, les decorateurs @Component, @Pipe, et @Directive sont des sous classes de @Injectable().  Ces décorateurs ajoutent des MetaDatas au code JavaScript transpilé à partir de nos fichiers TypeScript. Par défaut, le compilateur TypeScript rejette toutes les meta-données. Pour que ces metadatas soient integrées au JavaScript, l'option emitDecoratorMetadata doit être à true dans votre fichier tsconfig.json de votre projet.  Angular-CLI a dèjà configuré  votre tsconfig.json pour les prendre en charge

Pour commencer, je vous propose de vous créer un nouveau projet, comme ceci :

 

Nous allons maintenant créer notre service :

Voici un exemple de service de Logger injectable :

 

 

Attention, comme l'indique la log Angular-CLI de création du service, il n'est pas déclaré dans les providers. Il est donc nécessaire de la déclarer comme provider. Comme il s'agit d'un service transverse, je vous propose de la déclarer au niveau du module AppModule :

 

 

Si vous n'êtes pas familier avec la notion de module, je vous conseille de lire cet article.

 

Attention : Il faut se rappeler qu'une dépendance est un singleton dans la portée (scope) de l'injecteur. Lorsque nous déclarons notre service comme provider du module AppModule, ce premier est donc un singleton pour toute l'application (s'il n'est pas redéfini par ailleurs comme vous verrons par la suite…)

 

Pour information ecrire : 

providers: [LoggerService]

 

Et un raccouri pour écrire :

[{ provide: Logger, useClass: Logger }]

 

La propriété providers attend finalement un tableau d'objets provider. La première propriété de cet objet est un token pour identifier le provider. La seconde propriété indique comment créer le provider. Par exemple,  useClass : Logger indique qu'il faut intancier une classe de type Logger. En dehors de useClass, il existe d'autres propriétés comme useExisting qui permet de déclarer un alias (donc la même instance), useValue qui permet de déclarer un simple objet pour l'instancier comme classe.

 

Il est maintenant possible d'injecter notre service dans un autre composant Angular en le passant en paramètre du constructeur de ce dernier. Angular se charge de voir s'il existe une classe du token passé en paramètre dans ses providers. Donc pour ajouter du service LoggerService au component principal AppComposant, il suffit de l'ajouter à son constructeur comme ceci :

 

 

Comme nous avons déclaré ce service dans la propriété providers notre module root AppModule, il n'y a aucun problème d'injection puis le service est injectable dans l'intégralité de l'application. Cela fonctionne mais la notion d'injection de dépendance peut être plus fine que cela. Une application peut avoir plusieurs injecteurs !

 


 

 

La suite de cet article est disponible dans le livre Learn-Angular – Maîtriser les concepts du framework Angular pour développer des applications robustes.

 

Le livre est disponible sur 

 

 

 

William Koza

William Koza

Consultant Indépendant chez  
Passionné par la conception et le développement logiciel, j’ai rapidement pris le rôle de Technical Leader lors de mes premiers projets. Ces expériences ont ainsi pu me faire accéder à des rôles d’architecte dans des projets d’envergure. Aujourd'hui, j'exerce mon métier en tant qu'indépendant, et toujours avec la même passion.
William Koza

Les derniers articles par William Koza (tout voir)