依存性の注入とは
依存性の注入(DI)は Angular の基本概念で、コンポーネントなどのクラスが必要な依存関係を自動的に受け取れる仕組み。DI には依存関係を提供する「プロバイダー」と、それを受け取る「コンシューマー」の役割がある。Angular は「インジェクター」という仕組みを使い、依存関係の管理・提供を行う。インジェクターは既存のインスタンスを再利用し、なければ新たに作成する。通常は手動でインジェクターを作成する必要はなく、アプリ全体で使われるルートインジェクターが自動的に生成される。
依存関係を提供する
コンポーネントで依存関係として機能する必要がある HeroService をというクラスを作成してみる。
まずは、@Injectable デコレーターを追加してクラスを注入できることを示す。
@Injectable()
class HeroService {}
アプリケーションのルートレベルで提供する
providedIn を使用してアプリケーションのルートレベルでサービスを提供すると、そのサービスを他のすべてのクラスに注入できる。
@Injectable デコレーターで providedIn: 'root' を使用して、サービスを提供できる。
@Injectable({
providedIn: 'root'
})
class HeroService {}
コンポーネントレベルで提供する
@Component デコレーターの providers フィールドを使うと、そのコンポーネント専用のサービスを用意できる。例えば、HeroService をここで指定すると、そのコンポーネントのすべてのインスタンスと、そのコンポーネントの中で使われている他のコンポーネントやディレクティブでも HeroService が使えるようになる。つまり、そのコンポーネントのグループだけでサービスを共有できる。
@Component({
selector: 'hero-list',
template: '...',
providers: [HeroService]
})
class HeroListComponent {}
依存関係を注入する/消費する
依存関係を注入/消費するには inject 関数を使用する。
import {inject, Component} from 'angular/core';
@Component({/* ... */})
export class UserProfile {
private userClient = inject(HeroService);
constructor() {
const logger = inject(Logger);
}
}
inject 関数は、注入コンテキストの中で使うことができる。これは、通常コンポーネントやディレクティブ、サービス、パイプのクラスのプロパティ初期化子やコンストラクターの中を指す。
Angular では、コンポーネントがサービスを必要とすると、まずインジェクターはそのサービスの既存インスタンスがあるか確認する。なければ、登録されたプロバイダーを使って新しいインスタンスを作成し、インジェクターに保存する。すべての依存サービスが準備できたら、それらをコンポーネントのコンストラクターに渡して呼び出す。簡単に言うと、Angular は必要なサービスを見つけて作り、それを使ってコンポーネントを動かす。

注入可能なサービスの作成
Angularでは、サービスとコンポーネントはそれぞれ異なる役割を持つ。サービスはデータの取得や状態管理、入力の検証など特定の機能をもつクラスで、複数のコンポーネントから共有して使われることが多い。一方、コンポーネントは画面の表示やユーザーの操作を管理し、ビューとアプリケーションのロジックをつなぐ役割を担う。
注入可能なサービスの作成
Angular CLI を用いて、以下のコマンドを実行することでサービスクラスを作成できる。
ng generate service heroes/hero
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {}
サービスの注入
前述のとおり、inject 関数を使う。
import { inject } from "@angular/core";
export class HeroListComponent {
private heroService = inject(HeroService);
}