Services & Providers

Déclaration d'un Service

Pour déclarer un service Angular, il suffit de créer une classe TypeScript et de la décorer avec le décorateur @Injectable().

@Injectable()
export class BookRepository {
    ...
}

Pensez à utiliser un template ou live template dans votre IDE ou encore Angular CLI : yarn ng generate module book-repository

En essayant de l'injecter,

@Component({...})
export class BookPreviewComponent {
    constructor(private _bookRepository: BookRepository) {
    }
}

... vous remarquerez l'erreur suivante :

StaticInjectorError(AppModule)[BookPreviewComponent -> BookRepository]: 
  StaticInjectorError(Platform: core)[BookPreviewComponent -> BookRepository]: 
    NullInjectorError: No provider for BookRepository!

Angular essaie donc d'injecter une instance de BookRepository mais ne sait pas la produire.

Définition d'un Provider

Afin de pouvoir instancier un service, Angular a besoin d'un "provider" lui indiquant comment produire l'instance de ce service.

Cela se fait généralement via la propriété providers de la configuration du module associé mais nous verrons d'autres façons de faire plus tard. Cf. Portée des Services et Tree-Shakable Services.

useClass

La façon la plus commune de définir un provider est la suivante :

@NgModule({
    providers: [
        {
            provider: BookRepository,
            useClass: BookRepository
        }
    ]
})
export class BookCoreModule {
}

Cela veut dire que pour fournir une instance de la classe BookRepository, il suffit de l'instancier en lui passant en paramètre les dépendances dont elle a besoin. Cf. Injection d'un Service Angular.

Cette approche étant la plus commune, il est alors recommandé d'utiliser la syntaxe raccourcie suivante :

@NgModule({
    providers: [
        BookRepository
    ]
})
export class BookCoreModule {
}

useValue

Utilisation d'une valeur "hardcoded".

@NgModule({
    providers: [
        {
            provider: BookRepository,
            useValue: new FakeBookRepository()
        }
    ]
})
export class BookCoreModule {
}

useFactory

Comme son nom l'indique, cette propriété permet de définir l'instanciation du service via une fonction.

@NgModule({
    providers: [
        {
            provider: BookRepository,
            useFactory: () => {

                /* Useful for A/B testing. */
                if (isBTeam) {
                    return new BookRepositoryV2();
                }

                return new BookRepository();

            }
        }
    ]
})
export class BookCoreModule {
}

Dernière mise à jour