Внедрение зависимостей в Angular
Внедрение зависимостей (DI) — это шаблон проектирования, который помогает организовать и совместно использовать код в приложении, передавая зависимости классу, а не создавая их внутри него.
СОВЕТ: Ознакомьтесь с разделом «Основы» Angular, прежде чем переходить к этому подробному руководству.
По мере роста приложения разработчикам часто требуется повторно использовать функциональность и совместно применять её в разных частях кодовой базы. Внедрение зависимостей (DI) помогает достичь этого, позволяя передавать зависимости классу, а не создавать их непосредственно внутри него. Благодаря этому разные части приложения становятся более пригодными для повторного использования и ими проще управлять.
Внедрение зависимостей — популярный шаблон, поскольку он позволяет разработчикам решать распространённые задачи, такие как:
- Упрощение сопровождения кода: Внедрение зависимостей способствует чёткому разделению обязанностей, упрощает рефакторинг кода и сокращает дублирование.
- Масштабируемость: Модульную функциональность можно повторно использовать в разных частях приложения, упрощая его масштабирование.
- Улучшение тестирования: DI позволяет при необходимости использовать в модульных тестах тестовые двойники вместо реальных реализаций.
Как работает внедрение зависимостей в Angular?
Зависимость — это любой объект, значение, функция или сервис, необходимые классу для работы, но не создаваемые им самостоятельно. Вместо этого зависимость предоставляется извне, устанавливая чёткую связь между разными частями приложения.
Взаимодействие с системой внедрения зависимостей происходит двумя основными способами:
- Вы можете предоставлять значения, то есть делать их доступными.
- Вы можете внедрять значения, то есть запрашивать их в качестве зависимостей.
В данном контексте под «значениями» понимаются любые значения JavaScript, включая объекты, функции и экземпляры классов. К распространённым типам внедряемых зависимостей относятся:
- Значения конфигурации: константы, URL-адреса API, флаги функций и т. д., зависящие от среды
- Фабрики: функции, создающие объекты или значения с учётом условий во время выполнения
- Сервисы: классы, предоставляющие общую функциональность, бизнес-логику или состояние
Компоненты и директивы Angular автоматически участвуют в DI. Это означает, что в них можно внедрять зависимости, а сами они могут предоставлять зависимости для внедрения.
Что такое сервисы?
Сервис Angular — это класс TypeScript с декоратором @Service, который позволяет внедрять экземпляр класса в качестве зависимости. Сервисы — самый распространённый способ совместного использования данных и функциональности в приложении.
К распространённым типам сервисов относятся:
- Клиенты данных: абстрагируют детали отправки запросов на сервер для получения и изменения данных
- Управление состоянием: определяет состояние, совместно используемое несколькими компонентами или страницами
- Аутентификация и авторизация: управляет аутентификацией пользователей, хранением токенов и контролем доступа
- Ведение журналов и обработка ошибок: предоставляет общий API для ведения журналов или информирования пользователя о состояниях ошибок
- Обработка и отправка событий: обрабатывает события или уведомления, не связанные с конкретным компонентом, либо отправляет события и уведомления компонентам согласно шаблону «Наблюдатель»
- Вспомогательные функции: предоставляет повторно используемые вспомогательные функции, например для форматирования данных, проверки или вычислений
В следующем примере объявляется сервис с именем AnalyticsLogger:
import {Service} from '@angular/core';
@Service()
export class AnalyticsLogger {
trackEvent(category: string, value: string) {
console.log('Analytics event logged:', {
category,
value,
timestamp: new Date().toISOString(),
});
}
}
ПРИМЕЧАНИЕ: Декоратор @Service делает этот сервис доступным во всём приложении в виде синглтона. Такой подход рекомендуется для большинства сервисов.
ПОЛЕЗНО: Декоратор @Service — это удобная краткая форма записи для @Injectable({providedIn: 'root'}).
Внедрение зависимостей с помощью inject()
Вы можете внедрять зависимости с помощью функции Angular inject().
Ниже показан пример панели навигации, в которую внедряются AnalyticsLogger и сервис Angular Router, чтобы пользователи могли переходить на другую страницу с одновременным отслеживанием события.
import {Component, inject} from '@angular/core';
import {Router} from '@angular/router';
import {AnalyticsLogger} from './analytics-logger';
@Component({
selector: 'app-navbar',
template: `<a href="#" (click)="navigateToDetail($event)">Detail Page</a>`,
})
export class Navbar {
private router = inject(Router);
private analytics = inject(AnalyticsLogger);
navigateToDetail(event: Event) {
event.preventDefault();
this.analytics.trackEvent('navigation', '/details');
this.router.navigate(['/details']);
}
} Где можно использовать inject()?
Вы можете внедрять зависимости при создании компонента, директивы или сервиса. Вызов inject может находиться либо в constructor, либо в инициализаторе поля. Вот несколько распространённых примеров:
@Component({
/*...*/
})
export class MyComponent {
// ✅ In class field initializer
private service = inject(MyService);
// ✅ In constructor body
private anotherService: MyService;
constructor() {
this.anotherService = inject(MyService);
}
}
@Directive({...})
export class MyDirective {
// ✅ In class field initializer
private element = inject(ElementRef);
}
import {Service, inject} from '@angular/core';
import {HttpClient} from '@angular/common/http';
@Service()
export class MyService {
// ✅ In a service
private http = inject(HttpClient);
}
export const authGuard = () => {
// ✅ In a route guard
const auth = inject(AuthService);
return auth.isAuthenticated();
};
Angular использует термин «контекст внедрения» для обозначения любого места в коде, где можно вызвать inject. Чаще всего это происходит при создании компонентов, директив и сервисов. Подробнее см. в разделе «Контексты внедрения».
Дополнительные сведения см. в документации по API inject.
Следующие шаги
Теперь, когда вы знакомы с основами внедрения зависимостей в Angular, можно перейти к изучению создания собственных сервисов.
В следующем руководстве — «Создание и использование сервисов» — рассматриваются следующие темы:
- Как создать сервис с помощью Angular CLI или вручную
- Как работает шаблон
providedIn: 'root' - Как внедрять сервисы в компоненты и другие сервисы
В этом руководстве рассматривается самый распространённый вариант использования сервисов в приложениях Angular.
Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/di