Appearance
Injection de dépendances
Quel est le but (théorie)
L'injection de dépendances (DI) est un modèle de conception logicielle qui permet de supprimer les dépendances codées en dur dans notre application.
L'injection de dépendances est utilisée pour passer une instance d'une classe à un objet dépendant. Par exemple, si nous avons une variable, par exemple client, dans notre composant, Angular se chargera de fournir un objet client réel au composant.
Angular utilise une classe appelée Injector pour faire du DI. Injector est une instance singleton dont le travail consiste à créer des instances de classes. L'injecteur utilise un ensemble de règles pour répondre à la demande de dépendance.
Créer un service
Avant de parler des injections de dépendances, nous allons créer un service :
ts
export class MyService {
getTitle() {
return "Formation Angular"
}
}
Oui, un service est tout simplement une classe !
Problèmes :
- Comment nous l'avons vu avant, nous pouvons pas utiliser
new
car si le constructeur change, il faut changer le changer partout. - Nous créons à chaque fois une instance avec
new
La solution : L'injection de dépendance (DI).
Injection de dépendance
Voici le côté magique de l'injection de dépendance : nous récupérons l'instance dans le constructeur. Il suffit de créer un paramètre et de mettre le type.
ts
import { Component } from '@angular/core'
import { MyService } from './app.service.ts'
@Component({
selector: 'app-root',
template: '<h1>{{ title }}</h1>'
})
export class AppComponent {
title: string = ''
constructor(private myservice: MyService) {
this.title = myservice.getTitle()
}
}
Et en privilégiant le hook ngOnInit
avec l'injection raccourci de TypeScript :
ts
import {Component, OnInit} from '@angular/core';
import {MyService} from './app.service.ts';
@Component({
selector: 'app',
template: '<h1>{{title}}</h1>'
})
export class AppComponent implements OnInit {
title: string = ''
constructor(private myservice: MyService) { }
ngOnInit() {
this.title = this.myservice.getTitle();
}
}
Remarque sur private
ts
class AppComponent {
constructor(private myservice:MyService) {
}
}
Revient à faire :
ts
class AppComponent {
myservice:MyService
constructor(myservice:MyService) {
this.myservice = myservice;
}
}
Le provider
Méthode 1: propriété providers
Bien entendu, cela n'est pas suffisant. Ici, nous n'utilisons pas le mot clé new
. Normal, puisque nous utilisons le design pattern DI. C'est le provider qui se charge de créer les instances. Il faut donc les déclarer dans le module
ts
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {MyService} from './app.service.ts';
@NgModule({
imports: [BrowserModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [MyService]
})
export class AppModule {
}
C'est donc avec la propriété providers
que nous déclarons les services à instancier.
Méthode 2: propriété providedIn
Depuis Angular 9, vous pouvez indiquer que le service s'ajoute dans le provider directement dans le décorateur @Injectable()
ts
import { Injectable } from '@angular/core'
@Injectable({
providedIn: 'root'
})
export class MyService {
getTitle() {
return "Formation Angular"
}
}
La chaîne de caractères root
indique que la classe est fournie dans le module racine (AppModule
donc)