章: 第1章: Laravel内部と設計基盤
プロジェクトが成長するにつれて、AppServiceProvider の register() がどんどん膨らんでいく――これは多くのLaravelプロジェクトで起きる「初期化処理の肥大化」です。依存登録・イベント購読・ポリシー登録が一か所に混在すると、変更のたびに影響範囲が読めなくなります。
Service Providerを 関心ごとに分割して設計する ことで、初期化処理の見通しが劇的に改善します。アプリが起動するまでの流れを把握し、「誰が・何を・いつ登録するか」を明確にしていきましょう。
なぜService Provider設計が重要なのか
AppServiceProvider に集中させると次の問題が起きます。
- どのProviderが何を登録しているか追いにくくなる
boot()の処理順序が把握できず、初期化タイミングのバグが生じる- 機能単位での削除・差し替えが困難になる
チェックポイント:
register()はサービスのバインドのみ、boot()はバインド済みサービスを使った処理のみ。この区分を守るだけで設計が安定します。
register vs boot — 何をどちらに書くか
| 処理の種類 | register() |
boot() |
| コンテナへのバインド | ✅ | ❌ |
| ルーティング定義 | ❌ | ✅ |
| イベントリスナー登録 | ❌ | ✅ |
| ポリシー登録 | ❌ | ✅ |
| 他のサービスへのアクセス | ❌(未解決の可能性) | ✅ |
実装例
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Contracts\Clock;
use App\Services\SystemClock;
class DomainServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Clock::class, SystemClock::class);
}
public function boot(): void
{
// 起動後フック
}
}
Providerの分割指針
Providerを分けるときは「ドメイン単位」か「インフラ単位」を基準にすると迷いが減ります。
DomainServiceProvider— ビジネスロジック層の依存解決InfrastructureServiceProvider— 外部API・ストレージの差し込みEventServiceProvider— イベントとリスナーの対応表
AppServiceProvider は最小限に保ち、役割が増えたら専用Providerに切り出す習慣をつけましょう。
まとめ & 次のステップ
- Service Providerはアプリ起動時の初期化を担う「設定の窓口」
register()はバインドのみ、boot()はバインド後の処理のみ ― この区分を徹底するAppServiceProviderへの集中は避け、関心ごとにProviderを分割するconfig/app.phpのproviders配列で登録順を管理できることも意識しておく
次回は 第03回: ミドルウェアパイプライン詳細 で、HTTPリクエストがコントローラに届くまでの処理経路を学びます。