Lang x Lang

Service Providers

Table of Contents

Introduction

Service providers は、すべての Laravel application のブートストラッピングの中心的な場所です。あなた自身の application 、そして Laravel のすべてのコア services も、 service providers を通じてブートストラップされます。

しかし、"bootstrapped" とは何を意味するのでしょうか?一般的には、 service container のバインディング、 event listeners 、 middleware 、さらには routes を含むモノを登録することを意味します。 Service providers は、 application を設定するための中心的な場所です。

Laravel は、 mailer 、 queue 、 cache などのコア services をブートストラップするために、内部で数十の service providers を使用します。これらの providers の多くは deferred providers であり、すべての request でロードされるわけではなく、提供する services が実際に必要とされるときだけロードされます。

すべてのユーザー定義の service providers はbootstrap/providers.phpファイルに登録されています。以下のドキュメンテーションでは、独自の service providers の作成方法とそれらを Laravel application に register する方法を学びます。

NOTE

もし、 Laravel がリクエストをどのように処理し、内部でどのように動作するかについて詳しく学びたい場合は、 Laravel の request ライフサイクルに関するドキュメンテーションをご覧ください。

Writing Service Providers

すべての service providers はIlluminate\Support\ServiceProvider class を拡張します。ほとんどの service providers にはregisterbootの method が含まれています。register method 内で、service containerにバインドするものだけを記述するべきです。register method 内で event listeners、routes、または他の機能を登録しようとすることは絶対にしてはなりません。

Artisan CLI は make:provider command を用いて新しい provider を生成することができます。 Laravel は自動的にあなたの新しい provider をアプリケーションの bootstrap/providers.php ファイルに register します:

php artisan make:provider RiakServiceProvider

Register Method

前述の通り、registerの method 内では、service containerに対してバインドすることだけを行うべきです。event listeners、routes、または registerの method 内の他の機能を登録しようと試みるべきではありません。そうすると、まだロードされていない service provider によって提供される service を誤って使用する可能性があります。

基本的な service provider を見てみましょう。 service provider のメソッド内では、$appプロパティへのアクセスが常に可能で、これにより service container へのアクセスが可能になります:

<?php

namespace App\Providers;

use App\Services\Riak\Connection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->singleton(Connection::class, function (Application $app) {
            return new Connection(config('riak'));
        });
    }
}

この service provider は、register method だけを定義し、その method を使用してApp\Services\Riak\Connectionの実装を service container 内で定義します。まだ Laravel の service container についてよく知らないのであれば、そのドキュメンテーションをご覧ください。

bindingssingletons プロパティ

あなたの service provider が多くのシンプルなバインディングを登録する場合、各コンテナバインディングを手動で登録する代わりに bindings および singletons プロパティを使用することを希望するかもしれません。 service provider がフレームワークによって読み込まれると、それは自動的にこれらのプロパティを確認し、そのバインディングを 登録します。

<?php

namespace App\Providers;

use App\Contracts\DowntimeNotifier;
use App\Contracts\ServerProvider;
use App\Services\DigitalOceanServerProvider;
use App\Services\PingdomDowntimeNotifier;
use App\Services\ServerToolsProvider;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * All of the container bindings that should be registered.
     *
     * @var array
     */
    public $bindings = [
        ServerProvider::class => DigitalOceanServerProvider::class,
    ];

    /**
     * All of the container singletons that should be registered.
     *
     * @var array
     */
    public $singletons = [
        DowntimeNotifier::class => PingdomDowntimeNotifier::class,
        ServerProvider::class => ServerToolsProvider::class,
    ];
}

Boot Method とは

それでは、私たちの service providers の中でview コンポーザーを登録する必要がある場合はどうするべきでしょうか? これは boot method 内で行われるべきです。この method は、他のすべての service providers が登録された後に呼び出されます、つまり、フレームワークが登録した他のすべての services にアクセスできるということです:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        View::composer('view', function () {
            // ...
        });
    }
}

Boot Method Dependency Injection

あなたの service プロバイダのboot method に依存関係を types ヒントすることができます。service containerは、必要な依存関係を自動的に挿入します:

use Illuminate\Contracts\Routing\ResponseFactory;

/**
 * Bootstrap any application services.
 */
public function boot(ResponseFactory $response): void
{
    $response->macro('serialized', function (mixed $value) {
        // ...
    });
}

Registering Providers

すべての service providers は、bootstrap/providers.php設定ファイルに登録されています。このファイルはあなたの application の service providers の class 名を含む array を返します:

<?php

// This file is automatically generated by Laravel...

return [
    App\Providers\AppServiceProvider::class,
];

make:providerの Artisan command を呼び出すと、Laravel は自動的に生成されたプロバイダをbootstrap/providers.phpファイルに追加します。ただし、プロバイダ class を手動で作成した場合は、プロバイダ class を array に手動で追加する必要があります。

<?php

// This file is automatically generated by Laravel...

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\ComposerServiceProvider::class, // [tl! add]
];

Deferred Providers

あなたの provider がservice containerのみバインディングを登録している場合、登録されたバインディングのうちの 1 つが実際に必要になるまでその登録を延期することを選択できます。このような provider の読み込みを遅らせると、毎回の request でファイルシステムからロードされないため、 application のパフォーマンスが向上します。

Laravel は、遅延された service providers によって提供されるすべての services のリストをコンパイルし保存し、その service providers ー class の名前とともに保存します。そして、これらの services の一つを解決しようとするときだけ、Laravel は service providers をロードします。

provider の読み込みを遅延するには、\Illuminate\Contracts\Support\DeferrableProviderインターフェースを実装し、provides method を定義します。 provides method は、 provider によって登録された service container のバインディングを返すべきです。

<?php

namespace App\Providers;

use App\Services\Riak\Connection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->singleton(Connection::class, function (Application $app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array<int, string>
     */
    public function provides(): array
    {
        return [Connection::class];
    }
}

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use