Syringe — декларативный IoC Container на PHP

в 9:05, , рубрики: ioc, php, ооп

Инверсия управления (Inversion of Control) — важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в компьютерных программах (“Википедия”).

Простой как Pimple, мощный как Symfony DI

Syringe — простой IoC Container написанный на PHP с большим количеством возможностей и декларативной конфигурацией.

В нем реализованы: внедрение параметров, фабричные методы, основные виды инъекций, в том числе и через интерфейс, области видимости, внедрение тега и триггеры.

Далее возможности расписаны более подробно.

Первый пример

Есть класс Foo. Его конструктор принимает два параметра:

<?php

class Foo
{
    protected $a;
    protected $b;

    public function __construct($a, $b)
    {
        $this->a = $a;
        $this->b = $b;
    }
}

Описание сервиса в конфигурации выглядит так:

services:
  foo: 
    class:     'Foo',
    arguments: ['value1', 'value2']

Теперь при запросе сервиса foo, будет создан экземпляр класса MeFoo.

<?php

// container init...

$foo = $container->get('foo'); // MeFoo

Внедрение Doctrine

Более сложный пример описывает использование Doctrine в проекте.

Классу Foo требуется соединение с базой данных для своей работы:

<?php

class Foo
{
    protected $connection;

    public function __construct($connection)
    {
        $this->connection = $connection;
    }
    
    // ...
}

Конфигурация приложения будет выглядеть так:

# параметры доктрины
doctrine.configuration_paths: ['config/doctrine']
doctrine.db_parameters:
  driver: 'pdo_mysql'
  user: 'root'
  password: '1234'
  dbname: 'game'
  charset: 'UTF8'

services:
# сервис foo
  foo:
    class: 'Foo'
    arguments: ['@db_connection']

# сервисы доктрины
  doctrine.setup_configuration:
    factoryStaticMethod:
      - 'DoctrineORMToolsSetup'
      - 'createAnnotationMetadataConfiguration'
    arguments:
      - '%doctrine.configuration_paths%'

  doctrine.entity_manager:
    factoryStaticMethod:
      - 'DoctrineORMEntityManager'
      - 'create'
    arguments:
      - '%doctrine.db_parameters%'
      - '@doctrine.setup_configuration'
    alias: doctrine

  doctrine.connection:
    factoryMethod:
      - '@doctrine.entity_manager'
      - 'getConnection'
    alias: db_connection

При запросе сервиса foo в аргументы конструктора будет передано соединение с базой данных:

<?php

// init container ...

$foo = $container->get('foo');

Исходники: SyringeExampleDoctrine

Внедрение тега

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

В примере используется консольное приложение на основе Symfony Console Component:

services:
  app:
    class: 'SymfonyComponentConsoleApplication'
    calls:
      - ['addCommands', ['#console_commands']]

  command.foo:
    class: 'CommandFooCommand'
    tags: console_commands
  command.bar:
    class: 'CommandBarCommand'
    tags: console_commands

Сервисы, помеченные тегом console_commands, попадут списком в качестве аргумента функции addCommands.

Исходники: SyringeExampleConsole

Принцип работы

Конфигурация контейнера задается при помощи yaml, json или php формата.
При компиляции происходит процесс конвертирования конфигурации в массив php. Сконвертированная конфигурация экспортируется в файл, который используется для запуска контейнера.

Алгоритм компиляции следующий:

  1. конвертирование из внешнего формата (например yaml) в массив php,
  2. добавление конфигурации в Builder,
  3. разрешение зависимостей от параметров (%parameter.name%),
  4. отделение параметров от конфигурации сервисов,
  5. валидация и распределение конфигурации по коллекторам,
  6. слияние конфигурации из коллекторов и параметров.

После этого контейнер готов к работе.

Будущее

Конечно Syringe не вытеснит реализации DI из Symfony 2 или Zend2 — они предоставляют такую же функциональность и тесно интегрированы с фреймворками.

Однако цель его — не в этом. Его ниша — там, где нет топовых фреймворков. Он рассчитан на проекты без встроенного IoC Container и новые легкие приложения, где его еще только предстоит выбрать. И здесь он даст фору другим библиотекам, обгоняя их по функциональности и удобству.

Официальный сайт проекта: http://getsyringe.org/

Буду очень рад Вашим комментариям и предложениям!

Автор: AgreGADz

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js