Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fi1a/dependency-injection
Dependency injection container
https://github.com/fi1a/dependency-injection
container dependency-injection php
Last synced: about 1 month ago
JSON representation
Dependency injection container
- Host: GitHub
- URL: https://github.com/fi1a/dependency-injection
- Owner: fi1a
- License: mit
- Created: 2022-12-27T00:55:52.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2023-02-21T01:44:34.000Z (almost 2 years ago)
- Last Synced: 2024-05-20T13:03:51.541Z (8 months ago)
- Topics: container, dependency-injection, php
- Language: PHP
- Homepage:
- Size: 51.8 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Dependency injection container
[![Latest Version][badge-release]][packagist]
[![Software License][badge-license]][license]
[![PHP Version][badge-php]][php]
![Coverage Status][badge-coverage]
[![Total Downloads][badge-downloads]][downloads]
[![Support mail][badge-mail]][mail]Контейнер [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection),
может разрешать зависимости, создавать экземпляры и настраивать классы.
Поддерживает внедрение конструктора, свойств и методов.## Установка
Установить этот пакет можно как зависимость, используя Composer.
``` bash
composer require fi1a/dependency-injection
```## Использование контейнера
Для использования контейнера dependency injection, сначала необходимо в конфигурацию задать определения созданное с помощью builder'а.
Название определения обычно является именем интерфейса. Когда запрашивается тип для создания объекта, будет использоваться это определение.
Это происходит при вызове метода `get` непосредственно из контейнера. Объекты также создаются не явно при разрешении зависимостей.```php
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;
use Fi1a\Unit\DI\Fixtures\ClassC;
use Fi1a\Unit\DI\Fixtures\ClassCInterface;$config = new ContainerConfig();
$config->addDefinition(
Builder::build(ClassAInterface::class)
->defineClass(ClassA::class)
->getDefinition()
);$config->addDefinition(
Builder::build(ClassCInterface::class)
->defineClass(ClassC::class)
->defineConstructor([1, true])
->getDefinition()
);$container = new Container($config);
$container->get(ClassCInterface::class); // ClassCInterface
```Объект может быть определен несколькими способами:
- defineClass - сопоставление с конкретным классом;
- defineFactory - если реализация сложная и может быть лучше описана в коде, то следует использовать фабричный метод. При использовании фабричного метода, зависимости в аргументах автоматически разрешаются.
- defineObject - вернуть созданный экземпляр объекта.Также доступны следующие определения:
- defineConstructor - задает аргументы для конструктора класса определенного как defineClass;
- defineProperty - задает значение свойства объекта;
- defineProperties - задает ассоциативный массив со значениями свойств объекта;
- defineMethod - задает метод объекта, который необходимо вызвать с объявленными аргументами;
- defineMethods - задает ассоциативный массив с методами объекта, которые необходимо вызвать с объявленными аргументами.При отсутствии определения для запрашиваемого типа, контейнер выбросит исключение `Fi1a\DI\Exceptions\NotFoundException`.
## defineClass
Сопоставление с конкретным классом, определение аргументов конструктора, задание свойств и вызов методов:
```php
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;$config = new ContainerConfig();
$config->addDefinition(
Builder::build(ClassAInterface::class)
->defineClass(ClassA::class)
->defineConstructor([
'parameter1' => 10,
])
->defineProperty('property1', 100)
->defineMethod('setProperty2', [true])
->getDefinition()
);$container = new Container($config);
/** @var ClassA $object */
$object = $container->get(ClassAInterface::class); // ClassAInterface$object->property1; // 100
$object->property2; // true
```## defineFactory
Используется замыкание как фабричный метод:
```php
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;
use Fi1a\Unit\DI\Fixtures\ClassB;$config = new ContainerConfig();
$config->addDefinition(
Builder::build(ClassAInterface::class)
->defineFactory(function (ClassB $classB) {
$instance = new ClassA($classB);
$instance->property1 = 100;
$instance->property2 = true;return $instance;
})
->getDefinition()
);$container = new Container($config);
/** @var ClassA $object */
$object = $container->get(ClassAInterface::class); // ClassAInterface$object->property1; // 100
$object->property2; // true
```Использование фабричного метода в классе:
```php
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;
use Fi1a\Unit\DI\Fixtures\FactoryA;$config = new ContainerConfig();
$config->addDefinition(
Builder::build(ClassAInterface::class)
->defineFactory([FactoryA::class, 'factoryStatic'])
->getDefinition()
);$container = new Container($config);
/** @var ClassA $object */
$object = $container->get(ClassAInterface::class); // ClassAInterface$object->property1; // 100
$object->property2; // true
```## defineObject
Использовать уже созданный экземпляр объекта:
```php
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassB;
use Fi1a\Unit\DI\Fixtures\ClassBInterface;$config = new ContainerConfig();
$config->addDefinition(
Builder::build(ClassBInterface::class)
->defineObject(new ClassB())
->getDefinition()
);$container = new Container($config);
/** @var ClassB $object */
$object = $container->get(ClassBInterface::class); // ClassBInterface
```## Хелпер di
Доступен хелпер `di()`, возвращающий один экземпляр контейнера для регистрации опредлений в других пакетах.
```php
use Fi1a\DI\Builder;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;
use Fi1a\Unit\DI\Fixtures\ClassC;
use Fi1a\Unit\DI\Fixtures\ClassCInterface;di()->config()->addDefinition(
Builder::build(ClassAInterface::class)
->defineClass(ClassA::class)
->getDefinition()
);di()->config()->addDefinition(
Builder::build(ClassCInterface::class)
->defineClass(ClassC::class)
->defineConstructor([1, true])
->getDefinition()
);di()->get(ClassCInterface::class); // ClassCInterface
```## Создание определения из массива
Для создания определения из массива можно воспользоваться методом `buildFromArray` класса реализующего интерфейс `Fi1a\DI\ArrayBuilderInterface`:
```php
use Fi1a\DI\ArrayBuilder;
use Fi1a\DI\Container;
use Fi1a\DI\ContainerConfig;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;$config = new ContainerConfig();
$config->addDefinition(
$definition = ArrayBuilder::buildFromArray([
'name' => ClassAInterface::class,
'class_name' => ClassA::class,
'constructor' => [100, true],
'properties' => [
'property1' => 100,
'property2' => true,
],
'methods' => [
'setProperty1' => [100],
'setProperty2' => [true],
],
])->getDefinition()
);$container = new Container($config);
/** @var ClassA $object */
$object = $container->get(ClassAInterface::class); // ClassAInterface
```## Преобразование определения и коллекций в массив
Для преобразования определений и коллекций в массив, можно воспользоваться методом `definition`, или `collection` класса реализующего интерфейс `Fi1a\DI\ToArrayInterface`:
```php
use Fi1a\DI\ContainerConfig;
use Fi1a\DI\Builder;
use Fi1a\DI\ToArray;
use Fi1a\Unit\DI\Fixtures\ClassA;
use Fi1a\Unit\DI\Fixtures\ClassAInterface;$config = new ContainerConfig();
$definition = Builder::build(ClassAInterface::class)
->defineClass(ClassA::class)
->defineConstructor([
'parameter1' => 10,
])
->defineProperty('property1', 100)
->defineMethod('setProperty2', [true])
->getDefinition();$config->addDefinition($definition);
$toArray = new ToArray();
$array = $toArray->collection($config->getDefinitions()); // [[...], [...]]
$arrayDefinition = $toArray->definition($definition); // [...]
```[badge-release]: https://img.shields.io/packagist/v/fi1a/dependency-injection?label=release
[badge-license]: https://img.shields.io/github/license/fi1a/dependency-injection?style=flat-square
[badge-php]: https://img.shields.io/packagist/php-v/fi1a/dependency-injection?style=flat-square
[badge-coverage]: https://img.shields.io/badge/coverage-100%25-green
[badge-downloads]: https://img.shields.io/packagist/dt/fi1a/dependency-injection.svg?style=flat-square&colorB=mediumvioletred
[badge-mail]: https://img.shields.io/badge/mail-support%40fi1a.ru-brightgreen[packagist]: https://packagist.org/packages/fi1a/dependency-injection
[license]: https://github.com/fi1a/dependency-injection/blob/master/LICENSE
[php]: https://php.net
[downloads]: https://packagist.org/packages/fi1a/dependency-injection
[mail]: mailto:[email protected]