> For the complete documentation index, see [llms.txt](https://guide-angular.wishtack.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide-angular.wishtack.io/angular/dependency-injection/portee-des-services.md).

# 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](/files/-LCYMnFNv_-9ydBMXgFF)

### 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**.

{% tabs %}
{% tab title="book-preview\.component.ts" %}

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

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Il est préférable d'éviter cette approche et d'utiliser des [Inputs / Outputs pour interagir avec les "child components"](/angular/interaction-entre-composants.md). Autrement, les composants auront des comportements **différents et parfois imprédictibles** en fonction de l'endroit où ils sont utilisés.
{% endhint %}

### Lazy Loading

Dans le cas du [Lazy Loading](/angular/routing.md), 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".

{% hint style="warning" %}
Le danger dans ce cas est de réimporter un module définissant des "providers" et on se retrouve alors avec plusieurs instances du même "service".

Cela pose particulièrement problème pour les "**stateful services**".
{% endhint %}

## Feature Service Module

{% hint style="success" %}
Pour éviter le problème de double instanciation de "**stateful services**" décrit [ci-dessous](/angular/dependency-injection/portee-des-services.md#lazy-loading), la bonne pratique la plus commune est de créer **des modules dédiés** à la définition des "providers" de "**stateful services**" qui seront ensuite importés uniquement par le "root module" `AppModule`.
{% endhint %}

{% tabs %}
{% tab title="book-core.module.ts" %}

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

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="app.module.ts" %}

```typescript
@NgModule({
    imports: [
        BookCoreModule
    ]
})
export class AppModule {
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Cette approche reste fragile car à la moindre inattention, le module `BookCoreModule` peut se retrouver importé *(directement ou indirectement)* par d'autres modules "lazy loaded" et le même problème se reproduira.
{% endhint %}

## `Module.forRoot`

{% hint style="success" %}
La bonne pratique est de ne pas définir les "providers" de "stateful services" dans le module mais plutôt via une méthode statique conventionnellement nommée `forRoot` dont le résultat est importé par le "root module" `AppModule`.
{% endhint %}

{% tabs %}
{% tab title="book-core.module.ts" %}

```typescript
@NgModule({
})
export class BookCoreModule {

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

}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="app.module.ts" %}

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

{% endtab %}
{% endtabs %}

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](/angular/dependency-injection/tree-shakable-services.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://guide-angular.wishtack.io/angular/dependency-injection/portee-des-services.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
