Table of Contents

Dependency Injection

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

Суть паттерна заключается в том, чтобы не инициализировать лишний раз в конструкторе объекты вручную и не инициализировать лишний раз экземпляры классов в принципе (IoC).

Сервис-контейнер – класс, инициализирующий различные объекты, которые в последствии хранит в одном из своих полей.

Сервис – объекты, управляемые сервис-контейнером.

Реализации:

PHP и Symfony: http://fabien.potencier.org/what-is-dependency-injection.html

  • Dependency Injection без контейнеров
class User
{
  function __construct($storage)
  {
    $this->storage = $storage;
  }

  // ...
}

$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
  • Реализация возврата объекта в единственном экземпляре
class Container
{
  static protected $shared = array();

  // ...

  public function getMailer()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }

    $class = $this->parameters['mailer.class'];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());

    return self::$shared['mailer'] = $mailer;
  }
}
  • Реализация сервис-контейнера
class Container
{
  static protected $shared = array();

  protected $parameters = array();

  public function __construct(array $parameters = array())
  {
    $this->parameters = $parameters;
  }

  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this->parameters['mailer.username'],
      'password' => $this->parameters['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }

  public function getMailer()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }

    $class = $this->parameters['mailer.class'];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());

    return self::$shared['mailer'] = $mailer;
  }
}

Ресурсы

DI фреймворки и библиотеки

PHP

  • Pimple (Минималистичный DI контейнер)

w96k Ⓐ 2019-2022

2022-12-01 Thu 13:19