0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Laravel 5.6 ~] ServiceProvider内でシンプルなbindを行う方法が増えてた

Last updated at Posted at 2020-02-16

はじめに

初投稿です。

今まで業務ではlaravel5.5を使っており、最近新規のプロジェクトでlaravel6系統を使うようになったので、色々と変更点を確認しておりました(今更)。

その中で、ドキュメントにひっそりと追記されているにもかかわらず、あまり類似の情報をqiita等で見かけなかった(と思っている)物があったため、備忘録として投稿します。

環境

  • laravel 5.6 ~
    • ~ 5.5までは対応していません

対象

  • Laravelをそれなりに使っていて、DIコンテナ内で抽象と具象のbindについて大枠理解している方
    • 本記事ではDIの仕組み、それを使う動機等、「そもそもなぜこんなことをする必要があるか」について理解されている前提です。

基本的なバインド処理

さて、早速ですが基本的なバインド処理についてです。
最も基本的なinterfaceと実装クラスのbindingは以下のようになるかと思います。

app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // 抽象に対して具象クラスをbindingする
        // 以後、コンストラクタインジェクションやapp()の引数に(Abstract::class)で呼び出すと、Concreteクラスが返却される
        $this->app->bind(Abstract::class, Concrete::class);
        dd(Abstract::class); // => Concreteクラスが返却される
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

~ 5.5までのバインド方法

その上で、複数のバインドをまとめて行いたいユースケースについて考えます。
今まで自分が関わってきたプロジェクトで、バインドを複数まとめて行いたいとき(Repository Pattern等)、以下のような書き方をしていました。

app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    /**
     * bindingするinterfaceと実装クラスを$key => $valueで保持する
     *
     * @param array
     */
    private $repositoryBindings = [
        FooRepository::class => EloquentFooRepository::class,
        BarRepository::class => EloquentBarRepository::class,
    ];

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // すべてのbindingを回して登録する
        foreach($repositoryBindings as $abstract => $concrete) {
            $this->app->bind($abstract => $concrete);
        }
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

汚いというわけでもなく、特に問題なく動作するコードです。

5.6からのバインド方法

readoubleにしれっと追記されています。
https://readouble.com/laravel/5.6/ja/providers.html

シンプルなバインドを行うためのプロパティが追加されており、ここにbindを指定するだけで自動でbindingが行われる様になっています。
(ついでに$singletonのプロパティも用意されています)

app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    /**
     * 結合したいabstractとconcreteを登録. ここに記述されたものは自動でbindingされる
     *
     * @param array
     */
    public $bindings = [
        FooRepository::class => EloquentFooRepository::class,
        BarRepository::class => EloquentBarRepository::class,
    ];

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // ここで何も書かなくても$bindingsに指定があれば自動でbindが行われる
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

終わりに

大きなメリットがあるわけでもなく、ちょっとしたtipsでした。
ただ、やはりフレームワークが用意してくれている方式に乗っかれると気持ちがいいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?