Дисциплины - Объектно-ориентированное программирование

ООП в PHP - Фрэймворк Laravel - Внедрение зависимостей

Контейнер внедрения зависимости выступает в качестве фундамента для почти всех остальных возможностей Laravel.

Различные названия для возможности внедрения классов:

  • Контейнер приложения
  • Сервисный контроллер
  • Inversion of Control - инверсия управления (IoC)
  • Dependency Injection - внедрение зависимости (DI)

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

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

Обычное внедрение зависимости в php через конструктор:

class MailController{
 protected $mailer;
 public function __construct(Mailer $mailer){
   $this->mailer = $mailer;
 }
 public function welcome($user){
   return $this->mailer->mail($user->email, 'Welcome!')
 }
}

Данный класс MailController ожидает, что при его инстанцировании будет внедряться объект типа Mailer, после чего его методы будут ссылаться на этот экземпляр.

Основное преимущество внедрения зависимостей заключается в том, что мы можем менять внедряемые классы:

use App\Mailers\Mailer;
use App\Mailers\LocalMailer;
#...
$controller = new MailController(new LocalMailer);
//или
$controller = new MailController(new Mailer);

Автоматическе внедрение зависимостей в Laravel

Для внедрения зависимостей можно воспользоваться глобальным хелпером app()

class Bar
{
  public function __construct(){}
}
class Baz
{
  public function __construct(){}
}
class Foo
{
  public function __construct(Bar $bar, Baz $baz){}
}
$foo = app(Foo::class);

Основное преимущество такого способа внедрения - это автоматическое разрешение зависимостей. Хелперу app() не нужно указывать входящие параметры для класса Foo.

Дело в том, что обе зависимости Bar и Baz настолько просты, что контейнер может разрешить их без дополнительной информации. Контейнер читает подсказки типов в конструкторе класса Foo и разрешает экзепляры классов Bar и Baz, а затем внедряет их в новый класс Foo при его создании.

Автоматическое внедрение означет, что если класс не был явно привязан к контейнеру, но контейнер может выяснить, как его следует разрешить, то контейнер разрешит этот класс.

Как следствие, нам требуется выполнить привязку только тех классов, которые содержат неразрешимые (или уникальные) параметры.

Bind

Механизм связывания реализуется с помощью специального метода bind():

$this->app->bind('some', 'App\SomeClass');

Теперь, каждый раз, когда мы будем обращаться к сервис-контейнеру таким образом:

$some = $this->app->make('some');

Он будет возвращать вновь созданный объект класса App\SomeClass.

Если мы хотим, чтобы сервис-контейнер не только возвращал нам объект, но и пресетировал (преднастраивал) его, или если создание объекта класса требует каких-то особых аргументов, мы можем передать вторым параметром не название класса, а замыкание, и описать все необходимые действия:

$this->app->bind('some', function($app){
    $some = new \App\SomeClass('argument_1', 'argument_2');
    $some->setSomething('example');
    return $some;
});

Обратите внимание, что замыкание единственным аргументом принимает объект класса Illuminate\Foundation\Application, который и является этим самым сервис-контейнером, и он (сервис-контенер) также доступен через алиас фасада App, хелпер app(), а также как $this->app во многих классах Laravel. Таким образом, внутри замыкания можно вызывать данные из контейнера, которые были определены ранее. Например, так:

$this->app->bind('some', function($app){
    return new \App\SomeClass($app->make('some.else'));
});

Singleton

Следующий пример делает точно то же самое, что и предыдущий, однако объект класса будет создан однажды - при первом вызове, а все последующие обращения к тому же контейнеру будут возвращать созданный ранее объект:

$this->app->singleton('some', 'App\SomeClass');

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться
814301 БГУИР
814302 БГУИР
814303 БГУИР
894351 БГУИР
90421 БГУИР


Изображения Видео

1. Абстрактная фабрика https://www.youtube.com/watch?v=1mVONOCxfLg
2. Фабричный метод https://www.youtube.com/watch?v=5UqUDR6_2cY
3. Шаблон декоратор https://www.youtube.com/watch?v=Lwb9bm8yKD0
4. Dessign patterns on PHP https://github.com/domnikl/DesignPatternsPHP
5. Приёмы объектно-ориентированного проектирования. Паттерны проектирования Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес; [пер. с англ.: А. Слинкин науч. ред.: Н. Шалаев]. — Санкт-Петербург [и др.] : Питер, 2014. — 366 с. : ил. ; 24 см.
6. Приемы объектно-ориентированного проектирования. Паттерны проектирования Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес; [пер. с англ.: А. Слинкин науч. ред.: Н. Шалаев]. — Санкт-Петербург [и др.] : Питер, 2014. — 366 с. : ил. ; 24 см.
7. Ajax http://erud.by/ajax
8. Ajax http://erud.by/ajax
9. Ajax http://erud.by/ajax
10. Документация Laravel http://laravel.com
Задание к курсовой работе
Задание к курсовой работе
Вопросы к экзамену