https://github.com/devanych/di-container
Simple implementation of a PSR-11 dependency injection container
https://github.com/devanych/di-container
autowire autowiring container di php psr-11
Last synced: 4 months ago
JSON representation
Simple implementation of a PSR-11 dependency injection container
- Host: GitHub
- URL: https://github.com/devanych/di-container
- Owner: devanych
- License: mit
- Created: 2019-06-09T14:01:52.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-03-27T19:08:01.000Z (over 2 years ago)
- Last Synced: 2025-05-18T19:40:59.734Z (5 months ago)
- Topics: autowire, autowiring, container, di, php, psr-11
- Language: PHP
- Homepage:
- Size: 45.9 KB
- Stars: 12
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
# Dependency Injection Container
[](https://packagist.org/packages/devanych/di-container)
[](https://packagist.org/packages/devanych/di-container)
[](https://packagist.org/packages/devanych/di-container)
[](https://github.com/devanych/di-container/actions)
[](https://github.com/devanych/di-container/actions)
[](https://scrutinizer-ci.com/g/devanych/di-container/?branch=master)
[](https://scrutinizer-ci.com/g/devanych/di-container/?branch=master)A simple and lightweight container for dependency injection using autowiring that implements [PSR-11 Container](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md).
Support:
* Objects or class names.
* Anonymous functions (Closure instance).
* Scalars (integer, float, string, boolean).
* Arrays and nested arrays with all of the above data types.
A guide with a detailed description in Russian language is [available here](https://devanych.ru/development/prostoj-di-kontejner-s-podderzhkoj-avtovajringa).
## Installation
This package requires PHP version 7.4 or later.
```
composer require devanych/di-container
```## Usage
Create a container:
```php
use Devanych\Di\Container;$container = new Container();
// or with definitions array
$container = new Container($definitions);
```Sets in the container:
```php
/**
* Sets definition to the container.
*
* @param string $id
* @param mixed $definition
*/
$container->set($id, $definition);/**
* Sets multiple definitions at once; used in the constructor.
*
* @param array $definitions
*/
$container->setMultiple($definitions);
```Existence in the container:
```php
/**
* Returns 'true` if the dependency with this ID was sets, otherwise `false`.
*
* @param string $id
* @return bool
*/
$container->has($id);
```Gets from the container:
```php
/**
* Gets instance by definition from the container by ID.
*
* @param string $id
* @return mixed
* @throws Devanych\Di\Exception\NotFoundException If not found definition in the container.
* @throws Devanych\Di\Exception\ContainerException If unable to create instance.
*/
$container->get($id);/**
* Always gets a new instance by definition from the container by ID.
*
* @param string $id
* @return mixed
* @throws Devanych\Di\Exception\NotFoundException If not found definition in the container.
* @throws Devanych\Di\Exception\ContainerException If unable to create instance.
*/
$container->getNew($id);/**
* Gets original definition from the container by ID.
*
* @param string $id
* @return mixed
* @throws Devanych\Di\Exception\NotFoundException If not found definition in the container.
*/
$container->getDefinition($id);
```
If the definition is an anonymous function or class name, the `get()` method will execute the function and create an instance of the class only the first time, and subsequent `get()` calls will return the result already created.> If you need to execute a function and create an instance of the class every time, use the `getNew ()` method.
If the definition is a class name and there are dependencies in its constructor, then when calling the `get()` and `getNew ()` methods, at the time of creating the class instance, the container will recursively bypass all dependencies and try to resolve them.
> If the passed parameter `$id` to the methods `get()` and `getNew()` is a class name and has not been set previously by the `set()` method, an object of these class will still be created as if it had been set.
>
> If `$id` is not a class name and has not been set previously by the `set()` method, the exception `Devanych\Di\Exception\NotFoundException` will be thrown.## Examples of use
Simple usage:
```php
// Set string
$container->set('string', 'value');
$container->get('string'); // 'value'// Set integer
$container->set('integer', 5);
$container->get('integer'); // 5// Set array
$container->set('array', [1,2,3]);
$container->get('array'); // [1,2,3]// Set nested array
$container->set('nested', [
'scalar' => [
'integer' => 5,
'float' => 3.7,
'boolean' => false,
'string' => 'string',
],
'not_scalar' => [
'closure' => fn() => null,
'object' => new User(),
'array' => ['array'],
],
]);// Set object
$container->set('user', fn() => new User());
$container->get('user'); // User instance
// Or
$container->set('user', User::class);
$container->get('user');
// Or
$container->set(User::class, User::class);
$container->get(User::class);
// Or without setting via `set()`
$container->get(User::class);
```Usage of dependencies:
```php
/*
final class UserProfile
{
private $name;
private $age;public function __construct(string $name = 'John', int $age = 25)
{
$this->name = $name;
$this->age = $age;
}
}final class User
{
private $profile;public function __construct(UserProfile $profile)
{
$this->profile = $profile;
}
}
*/$container->set('user_name', 'Alexander');
$container->set('user_age', 40);$container->set('user', function (\Psr\Container\ContainerInterface $container): User {
$name = $container->get('user_name');
$age = $container->get('user_age');
$profile = new UserProfile($name, $age);
return new User($profile);
});$container->get('user');
// Or
$container->set(UserProfile::class, function (\Psr\Container\ContainerInterface $container): UserProfile {
return new UserProfile($container->get('user_name'), $container->get('user_age'));
});$container->get(User::class);
// Or with default values (`John` and `25`)
$container->get(User::class);
```Usage with dependencies and factories:
```php
/*
final class UserProfileFactory implements \Devanych\Di\FactoryInterface
{
public function create(\Psr\Container\ContainerInterface $container): UserProfile
{
return new UserProfile($container->get('user_name'), $container->get('user_age'));
}
}
*/$container->setMultiple([
UserProfile::class => UserProfileFactory::class,
// Or without autowiring
// UserProfile::class => fn => UserProfileFactory(),
// UserProfile::class => new UserProfileFactory(),
'user_name' => 'Alexander',
'user_age' => 40,
]);$container->get(User::class); // User instance
$container->get(UserProfile::class); // UserProfile instance
```