メシのタネ

めしのたねになるIT情報配信サイト


ServiceProviderって何してるの?DIの背後で動いてるやつの正体


  1. Laravel
  2. ServiceProviderって何してるの?DIの背後で動いてるやつの正体

先日DIの記事を書いたんですが、
DIって説明しようとすると、しれっとServiceProviderってやつが出てくるんですよね。
でも、「Providerにbindしてる」って言われても、お前それどこにおんねんってなる。

LaravelのプロジェクトにはProviderっていうディレクトリがあるんですが、
慣れないうちはそもそも存在に気づかないこともあります。

開発規模によってはそこまで触らないケースもあるかもしれませんが、
仕組みがわかってると、設計の見通しがよくなります。

この記事では、ServiceProviderって何?どこでどう使うの?というあたりを、
“とりあえず動いてるLaravel”からちょっと抜け出したい人向けに整理していきます。

ServiceProviderって、結局なにしてんの?

Laravelが起動する時に、「どのサービスをどう使うか」を先に知っておきたくて、
「あのクラスが必要になったらこれ渡しといてね」って登録しておく場所がServiceProviderです。

たとえばDIでこんなコード書いたとします:

public function __construct(UserRepository $repo)
{
    $this->repo = $repo;
}

このとき、LaravelはUserRepositoryって型ヒント見て、
「このインターフェース、どうやってインスタンス化するの?」ってなる。

ここでServiceProviderに登録されていれば、Laravelは

$this->app->bind(
    UserRepository::class,
    EloquentUserRepository::class
);

って設定を読んで、「あー、これね」ってなってくれる。

register()とboot()の違い

AppServiceProvider.phpの中には、だいたいこの2つのメソッドがあります。

public function register()
{
    // サービスの登録
}

public function boot()
{
    // 登録済みサービスを使った初期化
}
  • register():DIの設定を書く。まだ他のサービスは使えない。
  • boot():全サービスが登録されたあとに呼ばれる。イベント登録とか。

ぶっちゃけ最初はregister()だけ押さえとけばOK。
boot()は「ちょっと複雑な初期化が必要なとき」くらいで。

どこで使う?どう書く?

public function register()
{
    $this->app->singleton(MemoPad::class, function () {
        return new MemoPad();
    });
}

bind()singleton() の違いはざっくりこんな感じ:

メソッドインスタンス生成タイミング使いどころ
bind()毎回newされるステートレスなやつ
singleton()最初の1回だけnewされる状態を持たせたいときなど

何が嬉しいの?

  1. 依存の解決が明示的になる
     → どこで何が使われてるか見やすい。責務がはっきりする。
  2. テストが書きやすくなる
     → モックを差し替えるのが簡単になる
  3. 実装を変えても呼び出し側を触らなくて済む
     → EloquentからAPIクライアントに変えたくなったとき、Providerの設定だけ直せばいい

Laravelは「書くだけで渡ってくる快感」があるけど、
その裏側を知っておくと、「設計ってそういうことか」ってなる。

まとめ

ServiceProviderは、Laravelが
「このインターフェース、どう処理すればいい?」って聞きに来る場所。

  • register()でサービスを登録する
  • boot()は初期化に使えるけど最初は無理に使わなくていい
  • bindとsingletonの違いは使い分けよう(だいたいbindでいい)
  • 設計の意図が透けて見えるので、チーム開発でも効く

とりあえず「意味わからんけどAppServiceProviderに書いてる」状態から、
「なるほど、Laravelに“使い方”を教えてるんだな」ってとこまでわかれば十分です。

よかったらDIの記事も読んでみてください!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.

若い頃、「仕事中にハマったこと」や「誰かに共有したい技術的な気づき」をアウトプットしたくてブログを始めましたが、勢い任せでよく分からない記事を大量生産し、あえなく飽きて終了。

改めて今、キャリア15年分の経験や知識が、これからITエンジニアを目指す方や、同じような課題で悩んでいる現役エンジニアの「メシのタネ」になるような記事を残したいと思っています。
※過去の記事は見ると精神が崩壊するため、そっとしておいてください。

🛠 経歴という名の珍道中:
文系Fラン → 広告営業 → Web営業 → 通信営業 → Web進行 → 出版 → Web媒体運用 → ソフトウェアハウス → SES → フリーランス

専門教育も受けず、転職歴も多数。履歴書はまるで時系列の事故記録のようですが、試行錯誤を重ね、なんとかエンジニアとして食べています。

このブログでは、そんな「履歴書クラッシャー型エンジニア」が送る、
名古屋一敷居の低い、実務に役立つ技術ブログを目指します。

Laravel
LaravelのMiddlewareって意味あるの?仕組み・使いどころ・やらかしまで整理してみたNew!!
Laravel
ServiceProviderって何してるの?DIの背後で動いてるやつの正体New!!
Laravel
LaravelのサービスコンテナとDI、「書いてるだけで動く」コードの正体New!!
Laravel
Laravelのアーキテクチャ、実は誰もわかってない説New!!
ガジェット
【解説】Bluetoothヘッドホンでマイクが使えない理由と回避策まとめ(Mac対応)New!!
Laravel
Laravel Collection入門: mapとeachの違い、ちゃんと説明できますか?