Поиск по сайту
Ctrl + K
Вопросы по Angular

Как формируется иерархия зависимостей?

Иерархия зависимостей (или Dependency Hierarchy) — это концепция, используемая в Angular для управления зависимостями между компонентами и сервисами. Она позволяет Angular эффективно внедрять (инжектировать) зависимости в классы, такие как компоненты, директивы и сервисы, основываясь на их структуре и порядке инициализации.

Основы инъекции зависимостей

В Angular инъекция зависимостей управляется с использованием системы провайдеров. Каждый раз, когда компонент или сервис требует зависимость, Angular проверяет, доступна ли она в определенном инжекторе.

Пример создания сервиса

Представим, что у нас есть сервис LoggerService, который будет использоваться другими компонентами.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root', // Сделаем сервис доступным во всем приложении
})
export class LoggerService {
  log(message: string) {
    console.log(message);
  }
}

Создание компонента с зависимостями

Теперь создадим компонент, который будет использовать LoggerService.

import { Component } from '@angular/core';
import { LoggerService } from './logger.service';

@Component({
  selector: 'app-my-component',
  template: `<button (click)="doSomething()">Click me</button>`,
})
export class MyComponent {
  constructor(private logger: LoggerService) {}

  doSomething() {
    this.logger.log('Button was clicked!');
  }
}

Иерархия инжекторов

  • Корневой инжектор (Root injector): Он создается при загрузке приложения и является родителем для всех других инжекторов. Вся классическая инъекция зависимостей начинается с него.
  • Инжекторы компонентов (Component injectors): Каждый компонент также имеет свой собственный инжектор, который наследует зависимости от родительского инжектора. Если зависимость не найдена в текущем компоненте, Angular ищет в родительском инжекторе.
  • Локальные инжекторы: Вы также можете создавать локальные инжекторы для конкретных частей приложения, например, используя providers в декораторе @Component или @NgModule. Это позволяет изолировать зависимости и избегать конфликта имен.
  • Пример создания локального инжектора

    Допустим, вы хотите, чтобы LoggerService использовался только в одном компоненте и не был доступен во всем приложении:

    @Component({
      selector: 'app-another-component',
      template: `<button (click)="doSomething()">Click me too</button>`,
      providers: [LoggerService] // Теперь LoggerService будет доступен только здесь
    })
    export class AnotherComponent {
      constructor(private logger: LoggerService) {}
    
      doSomething() {
        this.logger.log('Another button was clicked!');
      }
    }
    

    Заключение

    Иерархия зависимостей в Angular упрощает управление доступностью и жизненным циклом ваших сервисов и компонентов. Понимание этой иерархии поможет вам организовать код более структурированно и избежать проблем с конфликтующими зависимостями. Следует помнить о том, что оптимальное использование инъекции зависимостей улучшает тестируемость вашего кода и способствует созданию масштабируемых приложений.