Portée des Services

Injector Tree

Angular ne dispose pas que d'un seul "injector" mais d'un arbre d'"injectors".

Root Injector

Tous les "providers" définis par les modules importés directement ou indirectement par l'AppModule sont injectés par le "root injector" et sont donc accessibles dans toute l'application.

Angular Services Scope

Component Injector

Chaque composant dispose d'un "injector" et peut définir des "providers" via la propriété providers de sa configuration.

Ces "providers" vont écraser les "providers" parents (ceux des composants parents ou du "root injector") et définir de nouvelles instances des services associés pour chaque instance du composant.

@Component({
    providers: [
        BookRepository
    ]
})
export class BookPreviewComponent {
}

Lazy Loading

Dans le cas du Lazy Loading, les modules Angular sont chargés de façon asynchrone et afin d'éviter de perturber le "root injector", ces derniers créent des "child injectors".

Feature Service Module

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

Module.forRoot

@NgModule({
})
export class BookCoreModule {

    static forRoot(): ModuleWithProviders {
        return {
            ngModule: BookCoreModule,
            providers: [
                BookRepository
            ]
        };
    }

}
@NgModule({
    imports: [
        BookCoreModule.forRoot()
    ]
})
export class AppModule {
}

Les modules "lazy loaded" qui importent le module BookCoreModule ne produiront alors pas de doublon.

Cette approche est malheureusement encore loin d'être parfaite :

  • la syntaxe forRoot est overkill ;

  • rien n'empêche l'import BookCoreModule.forRoot() de dans un module autre que le "root module" ;

  • tous les "stateful services" sont importés par le "root module" dès le chargement de l'application et peut-être inutilement.

C'est pour ces raisons qu'Angular 6 a introduit la notion de Tree-Shakable Services.

Dernière mise à jour