Laravel's Service Providers [Поставщики услуг]
Введение
Поставщики услуг (Service Providers) - это главное при начальной загрузке всех приложений Laravel. Ваше собственное приложение, а также все основные службы Laravel загружаются через поставщиков услуг.
Но что мы подразумеваем под «самозагрузкой»? В общем, мы имеем в виду регистрацию сущностей, включая регистрацию привязок сервисных контейнеров, прослушивателей событий, промежуточного программного обеспечения и даже маршрутов. Поставщики услуг - это центральное место для настройки вашего приложения.
Если вы откроете файл config/app.php
, включенный в Laravel, вы увидите массив providers
. Это все классы поставщиков услуг, которые будут загружены для вашего приложения. Обратите внимание, что многие из них являются «отложенными» поставщиками, то есть они не будут загружаться при каждом запросе, а только тогда, когда предоставляемые ими услуги действительно необходимы.
В этом обзоре вы узнаете, как написать собственных поставщиков услуг и зарегистрировать их в приложении Laravel.
Написание поставщиков услуг
Все поставщики услуг расширяют класс Illuminate\Support\ServiceProvider
. Большинство поставщиков услуг содержат методы register
и boot
. В рамках метода register
вы должны привязываться только к service container. Вы никогда не должны пытаться зарегистрировать какие-либо прослушиватели событий, маршруты или любую другую функциональность в методе register
.
Интерфейс командной строки Artisan может сгенерировать нового провайдера с помощью команды make:provider
:
php artisan make:provider RiakServiceProvider
Метод register
Как упоминалось ранее, в рамках метода register
вы должны привязываться только к service container. Вы никогда не должны пытаться зарегистрировать какие-либо прослушиватели событий, маршруты или любую другую функциональность в методе register
. В противном случае вы можете случайно воспользоваться услугой, предоставляемой поставщиком услуг, но еще не загруженной.
Давайте посмотрим на базовый service provider (поставщик услуг). В рамках любого из методов вашего поставщика услуг у вас всегда есть доступ к свойству $app
, которое предоставляет доступ к контейнеру службы:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Riak\Connection;
class RiakServiceProvider extends ServiceProvider
{
/**
* Зарегистрируйте любое приложение сервисов.
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection(config('riak'));
});
}
}
Этот поставщик услуг определяет только метод register
и использует этот метод для определения реализации Riak\Connection
в контейнере службы. Если вы не понимаете, как работает сервисный контейнер, ознакомьтесь с его документацией.
Свойства bindings
и singletons
Если ваш поставщик услуг (service provider) регистрирует много простых привязок, вы можете использовать свойства bindings
и singletons
вместо того, чтобы вручную регистрировать каждую привязку контейнера. Когда поставщик услуг загружается платформой, он автоматически проверяет эти свойства и регистрирует их привязки:
<?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
{
/**
* Все контейнеры bindings, которые необходимо зарегистрировать.
*
* @var array
*/
public $bindings = [
ServerProvider::class => DigitalOceanServerProvider::class,
];
/**
* Все контейнеры singleton, которые необходимо зарегистрировать.
*
* @var array
*/
public $singletons = [
DowntimeNotifier::class => PingdomDowntimeNotifier::class,
ServerProvider::class => ServerToolsProvider::class,
];
}
Метод boot
Итак, что, если нам нужно зарегистрировать композер вида в нашем сервис-провайдере? Это должно быть сделано в рамках метода boot
. Этот метод вызывается после того, как все другие поставщики услуг были зарегистрированы, то есть у вас есть доступ ко всем другим услугам, которые были зарегистрированы фреймворком:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Загрузите любые сервисы приложений.
*
* @return void
*/
public function boot()
{
view()->composer('view', function () {
//
});
}
}
Внедрение зависимости метода boot
Вы можете указать зависимости для метода boot
вашего поставщика услуг. Сервисный контейнер автоматически внедрит любые необходимые вам зависимости:
use Illuminate\Contracts\Routing\ResponseFactory;
public function boot(ResponseFactory $response)
{
$response->macro('caps', function ($value) {
//
});
}
Регистрация провайдеров
Все поставщики услуг зарегистрированы в файле конфигурации config/app.php
. Этот файл содержит массив providers
, в котором вы можете перечислить имена классов ваших поставщиков услуг. По умолчанию в этом массиве перечислены основные поставщики услуг Laravel. Эти поставщики загружают основные компоненты Laravel, такие как почтовая программа, очередь, кеш и другие.
Чтобы зарегистрировать своего провайдера, добавьте его в массив:
'providers' => [
// Другие поставщики услуг
App\Providers\ComposerServiceProvider::class,
],
Отложенные поставщики
Если ваш провайдер только регистрирует привязки в сервисном контейнере, вы можете отложить его регистрацию до тех пор, пока одна из зарегистрированных привязок не понадобится. Отсрочка загрузки такого провайдера улучшит производительность вашего приложения, поскольку оно не загружается из файловой системы при каждом запросе.
Laravel компилирует и хранит список всех услуг, предоставляемых отложенными поставщиками услуг, вместе с именем своего класса поставщика услуг. Затем, только когда вы пытаетесь разрешить одну из этих служб, Laravel загружает поставщика услуг.
Чтобы отложить загрузку поставщика, реализуйте интерфейс \Illuminate\Contracts\Support\DeferrableProvider
и определите метод provides
. Метод provides
должен возвращать привязки контейнера службы, зарегистрированные поставщиком:
<?php
namespace App\Providers;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
use Riak\Connection;
class RiakServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Зарегистрируйте любое приложение сервисов.
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection($app['config']['riak']);
});
}
/**
* Получите услуги, предоставляемые провайдером.
*
* @return array
*/
public function provides()
{
return [Connection::class];
}
}
Перевод:
https://laravel.com/docs/8.x/providers
Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)