Skip to main content
Практика завдань

Сервіси та впровадження залежностей в Angular

Що таке Сервіси?

Сервіс — це клас, який інкапсулює перезавантажувану логіку — отримання даних, бізнес-правила, ведення журналу тощо. Сервіси спільно використовуються між компонентами через систему Впровадження Залежностей (DI) Angular.


Створення Сервісу

typescript
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' // Доступний на рівні додатку (одиночний екземпляр) }) export class UserService { private apiUrl = '/api/users'; constructor(private http: HttpClient) {} getUsers(): Observable<User[]> { return this.http.get<User[]>(this.apiUrl); } getUserById(id: string): Observable<User> { return this.http.get<User>(\`\${this.apiUrl}/\${id}\`); } createUser(user: Partial<User>): Observable<User> { return this.http.post<User>(this.apiUrl, user); } }

Впровадження Сервісу

typescript
@Component({ selector: 'app-user-list', template: \` <ul> <li *ngFor="let user of users">{{ user.name }}</li> </ul> \` }) export class UserListComponent implements OnInit { users: User[] = []; // Впровадження сервісу через конструктор constructor(private userService: UserService) {} ngOnInit() { this.userService.getUsers().subscribe(users => { this.users = users; }); } }

Сучасна функція inject()

typescript
import { inject } from '@angular/core'; @Component({ /* ... */ }) export class UserListComponent { private userService = inject(UserService); // Конструктор не потрібен! }

Надання Сервісів

typescript
// 1. На рівні кореня (одиночний екземпляр — найпоширеніший) @Injectable({ providedIn: 'root' }) export class AuthService {} // 2. На рівні компонента (новий екземпляр для кожного компонента) @Component({ providers: [LoggerService] // Кожен компонент отримує свій власний екземпляр }) export class MyComponent {} // 3. На рівні модуля @NgModule({ providers: [AnalyticsService] }) export class AnalyticsModule {}

Токени Впровадження

Для залежностей, що не є класами:

typescript
import { InjectionToken } from '@angular/core'; export const API_URL = new InjectionToken<string>('API_URL'); // Надання @NgModule({ providers: [ { provide: API_URL, useValue: 'https://api.example.com' } ] }) // Впровадження constructor(@Inject(API_URL) private apiUrl: string) {} // або private apiUrl = inject(API_URL);

Типи Провайдерів

ПровайдерОписПриклад
useClassНадати інший клас{ provide: Logger, useClass: FileLogger }
useValueНадати статичне значення{ provide: API_URL, useValue: 'https://...' }
useFactoryНадати через фабричну функцію{ provide: Service, useFactory: () => new Service() }
useExistingПсевдонім для існуючого провайдера{ provide: OldService, useExisting: NewService }

Важливо:

Сервіси інкапсулюють перезавантажувану логіку і спільно використовуються через Впровадження Залежностей. Використовуйте @Injectable({ providedIn: 'root' }) для одиночних екземплярів на рівні додатку. Використовуйте сучасну функцію inject() замість впровадження через конструктор, коли це можливо. DI робить код тестованим (мок-сервіси в тестах) і модульним (заміна реалізацій).

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань