Yet another php dependency injection container

dev-master 2013-07-29 16:32 UTC

This package is not auto-updated.

Last update: 2024-05-21 01:51:10 UTC


README

YetAnother DI — гибкий DI-контейнер, создающий экземпляры классов и их зависимости на основании параметров конструктора класса. Вам больше не потребуются конфиги, описания зависимостей, именование сервисов, или анонимные функции — всю информацию о связях контейнер будет брать из конструкторов. В отличии от популярных DI-контейнеров, данный контейнер работает только c Singletone'ами, т.е. с объектами, которые создаются 1 раз.

Установка

Рекомендуемая установка через composer:

{
    "require": {
        "yetanother/di": "dev-master"
    }
}

Создание контейнера

use YetAnother\DI\Container;

$container = new Container();

Создание объектов

$myObject = $container->get('MyClass');
// или
$myObject = $container['MyClass'];

Получение объектов

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

$myObject = $container->get('MyClass');
// или
$myObject = $container['MyClass'];

Проверка существования

$container->has('MyClass'); // true/false
// или
isset($container['MyClass']);

Ручное добавление объектов

$myObject = new MyClass();
$container->push($myObject);
// или
$container[] = $myObject;

// после добавления можно получить доступ к объекту по имени класса:
$container->get('MyClass') === $myObject; // true

Удаление объектов из контейнера

$container->remove('MyClass');
// или
unset($container['MyClass']);

Создание объектов с зависимостями

Допустим, класс MyModel зависит от класса Database, и эта зависимость описана в конструкторе:

class MyModel
{
    private $db;

    public function __construct(Database $db)
    {
        $this->db = $db;
        echo 'MyModel created';
    }
}
class Database()
{
    public function __construct()
    {
        echo 'Database created';
    }
}

Тогда, при создании объекта класса MyModel, сначала будет создан объект Database:

$myModel = $container->get('MyModel');
// Database created
// MyModel created

Но, если объект класа Database уже создан и хранится в контейнере, то он будет передан в конструктор MyModel, т.е. второй раз создаваться уже не будет:

$db = $container->get('Database');
// Database created
$myModel = $container->get('MyModel');
// MyModel created

Таким образом, создаются все зависимости по цепочке.

Добавление функционала при создании объектов

Если вам необходимы дополнительные действия при создании объектов, можно описать их в анонимной функции:

$container->set('Database', function () {
    $db = new Database();
    $db->connect();
    return $db;
});
// или
$container['Database'] = function () {...};

Для того чтобы использовать объекты в анонимной функции, передайте их в качестве параметров функции:

$container->set('UserModel', function (Database $db, Session $session) {
    ...
});

Зависимости от контейнера

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

class MyClass
{
    public function __construct(Container $container)
    {
        ...
    }
}
$container->set('MyClass', function (Container $container) {
    ...
});