Сервис-провайдеры
11.x
.
Почему это важно?
Введение
Сервис-провайдеры лежат в основе первоначальной загрузки всех приложений на Laravel. И ваше приложение, и все базовые сервисы Laravel загружаются через сервис-провайдеры.
Но что мы понимаем под “первоначальной загрузкой”? В общих чертах, мы имеем ввиду регистрацию таких вещей, как биндингов в IoC-контейнер (фасадов и т.д.), слушателей событий, фильтров роутов и даже самих роутов. Сервис-провайдеры – центральное место для конфигурирования вашего приложения.
Если вы откроете файл config/app.php
, поставляемый с Laravel, то увидите массив providers
. В нём перечислены все классы сервис-провайдеров, которые загружаются для вашего приложения. Конечно, многие из них являются “отложенными” провайдерами, т.е. они не загружаются при каждом запросе, а только при необходимости.
В этом обзоре вы узнаете, как создавать свои собственные сервис-провайдеры и регистрировать их в своём приложении.
Использование сервис-провайдеров
Все сервис-провайдеры наследуют класс Illuminate\Support\ServiceProvider
. В большинстве сервис-провайдеров есть методы register
и boot
. В методе register
вы должны только привязывать свои классы в сервис-контейнер. Никогда не пытайтесь зарегистрировать слушателей событий, роуты и какие-либо другие возможности в методеregister
.
С помощью Artisan CLI можно создать новый провайдер командой make:provider
:
php artisan make:provider RiakServiceProvider
Метод Register
Как уже было сказано, внутри метода register
, вы должны только привязывать свои классы в сервис-контейнер. Никогда не пытайтесь зарегистрировать слушателей событий, роуты и какие-либо другие возможности в методе register
. Иначе вы можете случайно обратиться к сервису, предоставляемому сервис-провайдером, который ещё не был загружен.
Давайте взглянем на простой сервис-провайдер. Из любого метода вашего сервис-провайдера у вас всегда есть доступ к свойству $app
, которое предоставляет доступ к сервис-контейнеру:
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* Регистрация привязки в контейнере.
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection(config('riak'));
});
}
}
Этот сервис-провайдер только определяет метод register
и использует его, чтобы определить реализацию Riak\Connection
в сервис-контейнере. Если вы не понимаете как работает сервис-контейнер, прочитайте его документацию.
Метод 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 загрузит нужный сервис-провайдер только когда в процессе работы приложению понадобится один из этих сервисов.
Для того, чтобы сделать сервис-провайдер отложенным, установите свойство defer
равным true
и определите метод provides
. Метод provides
должен вернуть привязки сервис-контейнера, зарегистрированные в вашем провайдере:
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* Задаёт отложена ли загрузка провайдера.
*
* @var bool
*/
protected $defer = true;
/**
* Регистрация сервис-провайдера.
*
* @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];
}
}