Вступление

Поставщики услуг являются центральным местом при начальной загрузке приложений Laravel. Ваше собственное приложение, а также все основные сервисы Laravel загружаются через сервис-провайдеров.

Но что мы подразумеваем под «начальной загрузкой»? В общем, мы имеем в виду регистрациювещей, включая регистрацию привязок сервисных контейнеров, прослушивателей событий, промежуточного программного обеспечения и даже маршрутов. Поставщики услуг являются центральным местом для настройки вашего приложения.

Если вы откроете файл, включенный в Laravel, вы увидите массив. Это все классы поставщика услуг, которые будут загружены для вашего приложения. Обратите внимание, что многие из них являются «отложенными» поставщиками, то есть они будут загружаться не при каждом запросе, а только тогда, когда услуги, которые они предоставляют, действительно необходимы.config/app.phpproviders

В этом обзоре вы узнаете, как написать своих собственных поставщиков услуг и зарегистрировать их в своем приложении Laravel.

 

Написание поставщиков услуг

Все поставщики услуг расширяют класс. Большинство поставщиков услуг содержат и метод. Внутри метода вы должны только связать вещи в сервисный контейнер . Вы никогда не должны пытаться зарегистрировать какие-либо слушатели событий, маршруты или любые другие функции внутри метода.Illuminate\Support\ServiceProviderregisterbootregisterregister

Artisan CLI может сгенерировать нового поставщика с помощью команды:make:provider

php artisan make:provider RiakServiceProvider

 

Метод регистрации

Как упоминалось ранее, в registerметоде вы должны только связывать вещи в сервисный контейнер . Вы никогда не должны пытаться зарегистрировать какие-либо слушатели событий, маршруты или любые другие функции внутри registerметода. В противном случае вы можете случайно воспользоваться услугой, предоставляемой поставщиком услуг, который еще не загружен.

Давайте посмотрим на поставщика основных услуг. В любом из методов вашего поставщика услуг вы всегда имеете доступ к $appсвойству, которое предоставляет доступ к контейнеру службы:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}

Этот поставщик услуг определяет только registerметод и использует этот метод для определения реализации в контейнере службы. Если вы не понимаете, как работает сервисный контейнер, ознакомьтесь с его документацией .Riak\Connection

В bindingsИ singletonsСвойства

Если ваш поставщик услуг регистрирует много простых привязок, вы можете использовать свойства bindingsand singletonsвместо ручной регистрации каждой привязки контейнера. Когда поставщик услуг загружается платформой, он автоматически проверяет эти свойства и регистрирует их привязки:

<?php

namespace App\Providers;

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

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,
    ];
}

 

Метод загрузки

Итак, что если нам нужно зарегистрировать view composer у нашего поставщика услуг? Это должно быть сделано в рамках bootметода. Этот метод вызывается после регистрации всех других поставщиков услуг, что означает, что у вас есть доступ ко всем другим службам, которые были зарегистрированы платформой:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

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

Boot Method Inpendency Injection

Вы можете ввести зависимости подсказки для bootметода вашего поставщика услуг . Контейнерный сервис будет автоматически вводить какую - либо зависимость, нужно:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $response)
{
    $response->macro('caps', function ($value) {
        //
    });
}

 

Регистрация провайдеров

Все поставщики услуг зарегистрированы в файле конфигурации. Этот файл содержит массив, в котором вы можете перечислить имена классов ваших поставщиков услуг. По умолчанию в этом массиве указан набор основных поставщиков услуг Laravel. Эти провайдеры загружают основные компоненты Laravel, такие как почтовая программа, очередь, кэш и другие.config/app.phpproviders

Чтобы зарегистрировать своего провайдера, добавьте его в массив:

'providers' => [
    // Other Service Providers

    App\Providers\ComposerServiceProvider::class,
],

 

Отложенные провайдеры

Если ваш провайдер регистрирует только привязки в контейнере службы , вы можете отложить его регистрацию до тех пор, пока одна из зарегистрированных привязок фактически не понадобится. Отсрочка загрузки такого провайдера улучшит производительность вашего приложения, поскольку оно не загружается из файловой системы при каждом запросе.

Laravel компилирует и хранит список всех услуг, предоставляемых отложенными поставщиками услуг, вместе с именем его класса поставщиков услуг. Тогда, только когда вы попытаетесь разрешить одну из этих услуг, Laravel загрузит поставщика услуг.

Чтобы отложить загрузку провайдера, реализуйте интерфейс и определите метод. Метод должен вернуть контейнер службы привязок , зарегистрированных поставщиком:\Illuminate\Contracts\Support\DeferrableProviderprovidesprovides

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;

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

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