введение в Laravel 5

Post on 23-Jan-2017

45 views 0 download

Transcript of введение в Laravel 5

Введение в Laravel 5Сервис-контейнер в Laravel

Сервис-контейнерсредство для управлениязависимостями классов

ивнедрения зависимостей.

Внедрение зависимостей (DI)конструктор или метод-сеттер

namespace App\Jobs;

class PurchasePodcast implements SelfHandling{ protected $mailer;

public function __construct(Mailer $mailer) { $this->mailer = $mailer; }

сервис внедрёнможем легко подменить его с другой реализацией

Можно легко создать «mock» или фиктивную реализацию при тестировании приложения

Связывание

Все привязки сервис-контейнеров будут зарегистрированы в сервис-провайдерах

Сервис-провайдеры - основа «первоначальной загрузки» Laravel

Приложение и все базовые сервисы загружаются через сервис-провайдеры

«Первоначальная загрузка»регистрация таких вещей как:

● привязки сервис-контейнера● слушатели событий (event listener)● посредники (middleware)● маршруты (routes)

Сервис-провайдерыцентральное место для настройки приложения

Если открытьconfig/app.php

поставляемый с Laravelто увидим… (deferred)

'providers' => [

/* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,

Если классы не зависят от интерфейсовне надо связывать их в контейнере

Не нужно объяснять контейнеру, как создавать эти объектыСервисы отражения PHP (Reflection)

В сервис-провайдере всегда есть доступ к контейнеру через переменную экземпляра $this->app

Привязка методом bind()

Первый аргумент имя класса или интерфейсаВторой замыкание (Closure), которое возвращает

экземпляр класса

$this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app['HttpClient']);});

Получаем сам контейнер в виде аргумента «резолвера»Затем можно использовать контейнер, чтобы получать под-

зависимости создаваемого объекта

Связывание синглтона

singleton()привязывает класс или интерфейс к контейнеру

должен быть создан только один раз

$this->app->singleton('FooBar', function ($app) { return new FooBar($app['SomethingElse']);});

Связывание существующего экземпляра класса с контейнером

instance()Привязка существующего экземпляра к контейнеру

экземпляр будет всегда возвращаться при последующих обращениях к контейнеру

$fooBar = new FooBar(new SomethingElse);

$this->app->instance('FooBar', $fooBar);

Связывание интерфейса с реализацией

<?phpnamespace App\Handlers\Commands;

use App\Commands\CreateOrder;use Pusher\Client as PusherClient;

class CreateOrderHandler {

/** * Экземпляр клиента Pusher SDK. */ protected $pusher;

public function __construct(PusherClient $pusher) { $this->pusher = $pusher; }

<?phpnamespace App\Contracts;

interface EventPusher {

/** * Push a new event to all clients. * * @param string $event * @param array $data * @return void */ public function push($event, array $data);

}

$this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');

<?phpnamespace App\Handlers\Commands;

use App\Contracts\EventPusher;

class CreateOrderHandler {

/** * Экземпляр клиента Pusher SDK. */ protected $pusher;

/** * Создание нового экземпляра класса. * * @param EventPusher $pusher * @return void */ public function __construct(EventPusher $pusher) { $this->pusher = $pusher; }

Контекстное связывание

$this->app->when('App\Handlers\Commands\CreateOrderHandler') ->needs('App\Contracts\EventPusher') ->give('App\Services\PubNubEventPusher');

$this->app->when('App\Handlers\Commands\CreateOrderHandler') ->needs('App\Contracts\EventPusher') ->give(function () { // Извлечение зависимости... });

Получение из контейнера

$fooBar = $this->app->make('FooBar');

$fooBar = $this->app['FooBar']; // ArrayAccess

public function __construct(EventPusher $pusher)

Варианты

События контейнера

$this->app->resolving(function ($object, $app) { // Вызывается при извлечении объекта любого типа...});

$this->app->resolving(FooBar::class, function (FooBar $fooBar, $app) { // Вызывается при извлечении объекта типа "FooBar"...});