Что такое внедрение зависимостей в Angular?

Внедрение зависимостей (Dependency Injection, DI) - это паттерн проектирования, широко используемый в Angular, который позволяет управлять зависимостями объектов и обеспечивает связывание компонентов и сервисов в приложении. В Angular DI играет ключевую роль, обеспечивая легкость разработки, тестируемость и повторное использование кода.

DI позволяет создавать экземпляры классов и передавать их в другие классы, где они могут быть использованы. Это осуществляется путем определения зависимостей в конструкторе класса или через аннотации.

Давайте рассмотрим пример, чтобы лучше понять внедрение зависимостей в Angular.

Предположим, у нас есть сервис UserService, который отвечает за управление пользователями:

import { Injectable } from '@angular/core'

@Injectable()
export class UserService {
	getUsers(): string[] {
		return ['John', 'Jane', 'Bob']
	}
}

Сервис помечен декоратором @Injectable(), который указывает Angular, что этот класс является инъектируемым сервисом.

Теперь давайте создадим компонент UserListComponent, который будет использовать UserService для получения списка пользователей:

import { Component } from '@angular/core'
import { UserService } from './user.service'

@Component({
	selector: 'app-user-list',
	template: `
		<h2>User List</h2>
		<ul>
			<li *ngFor="let user of users">{{ user }}</li>
		</ul>
	`
})
export class UserListComponent {
	users: string[]

	constructor(private userService: UserService) {}

	ngOnInit() {
		this.users = this.userService.getUsers()
	}
}

В этом примере мы определяем userService в конструкторе компонента и помечаем его модификатором доступа private. Это сообщает Angular, что мы хотим внедрить экземпляр UserService в этот компонент.

Затем мы используем метод getUsers() из userService в методе ngOnInit(), чтобы получить список пользователей и присвоить его свойству users, которое используется в шаблоне для отображения списка.

Теперь, когда компонент UserListComponent будет создаваться, Angular автоматически создаст экземпляр UserService и внедрит его в конструктор компонента.

Чтобы использовать UserListComponent, мы должны добавить его в другой компонент или в шаблон родительского компонента:

<app-user-list></app-user-list>

Angular заботится о создании экземпляра UserService и передаче его в UserListComponent.

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

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