...

вторник, 15 июля 2014 г.

[Из песочницы] Syringe — декларативный IoC Container на 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, будет создан экземпляр класса Me\Foo.



<?php

// container init...

$foo = $container->get('foo'); // Me\Foo


Внедрение 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:
- 'Doctrine\ORM\Tools\Setup'
- 'createAnnotationMetadataConfiguration'
arguments:
- '%doctrine.configuration_paths%'

doctrine.entity_manager:
factoryStaticMethod:
- 'Doctrine\ORM\EntityManager'
- '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: 'Symfony\Component\Console\Application'
calls:
- ['addCommands', ['#console_commands']]

command.foo:
class: 'Command\FooCommand'
tags: console_commands
command.bar:
class: 'Command\BarCommand'
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/


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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий