Appearance
A quoi sert @Injectable dans Angular ?
Dans Angular, @Injectable
est une décoration qui indique qu'une classe peut être utilisée comme un service injectable. Cela signifie que vous pouvez injecter une instance de cette classe dans d'autres classes de votre application, comme un composant ou un autre service.
Que se passe t-il si on n'utilise pas @Injectable ?
Si vous omettez la décoration @Injectable
sur une classe qui est utilisée comme un service injectable dans votre application Angular, vous pouvez rencontrer des erreurs lors de la compilation ou de l'exécution de votre application.
Voici un exemple de déclaration d'un service sans la décoration @Injectable
:
ts
import { HttpClient } from '@angular/common/http'
export class MyService {
constructor(private http: HttpClient) {}
}
Si vous essayez d'injecter cette instance de MyService
dans un composant ou un autre service de votre application, vous pouvez obtenir l'erreur suivante lors de la compilation :
Error: Can't resolve all parameters for MyService: (?).
Cette erreur se produit car Angular ne peut pas résoudre les dépendances de MyService
, car il ne sait pas que cette classe peut être utilisée comme un service injectable.
Pour résoudre cette erreur, vous devez ajouter la décoration @Injectable
à votre classe de service pour indiquer à Angular qu'elle peut être utilisée comme un service injectable :
ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(private http: HttpClient) {}
}
Vous pouvez ensuite injecter cette instance de MyService
dans un composant en utilisant le décorateur @Component
et en la déclarant dans la liste des dépendances du constructeur du composant :
ts
import { Component } from '@angular/core';
import { MyService } from './my.service';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
standalone: true,
})
export class MyComponent {
constructor(private myService: MyService) { }
}
Pourquoi utiliser providedIn
?
Utiliser providedIn
peut être une bonne option pour améliorer les performances de votre application grâce au "tree shaking" et pour faciliter les tests unitaires.
Le "tree shaking" est une technique utilisée par les outils de build modernes pour optimiser la taille de votre application en ne conservant que le code qui est utilisé dans votre application. Si vous utilisez providedIn
pour déclarer votre service, le code de votre service sera automatiquement inclus dans le build de votre application uniquement si l'instance de votre service est utilisée par un composant ou un autre service de votre application. Cela peut contribuer à réduire la taille de votre application et à améliorer ses performances.
En ce qui concerne les tests unitaires, utiliser providedIn
peut rendre la configuration de vos tests unitaires plus simple et plus rapide, car vous n'avez pas à vous soucier de l'enregistrement de votre service dans un module spécifique. Vous pouvez simplement importer votre service et le déclarer dans la liste des dépendances de votre composant ou de votre service de test, comme vous le feriez normalement.
Utiliser providedIn
La propriété providedIn
est utilisée dans la décoration @Injectable
pour indiquer à Angular où enregistrer l'instance de ce service.
Voici un exemple de déclaration d'un service avec @Injectable
et la propriété providedIn
:
ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() {}
}
Dans cet exemple, la valeur de providedIn
est 'root'
, ce qui signifie que l'instance de MyService
sera enregistrée dans le conteneur de services racine d'Angular et qu'il sera disponible pour tous les composants de votre application.
Mettre le module dans provideIn
Pour enregistrer l'instance de votre service dans un module spécifique, vous devez effectivement importer le module et le spécifier dans la propriété providedIn
de la décoration @Injectable
.
ts
import { Injectable } from '@angular/core';
import { MyModule } from './my.module';
@Injectable({
providedIn: MyModule
})
export class MyService {
constructor() {}
}
Dans cet exemple, l'instance de MyService
sera enregistrée dans le conteneur de services du module MyModule
, ce qui signifie qu'elle ne sera disponible que pour les composants du module MyModule
et de ses sous-modules.