Skip to content

Commit

Permalink
Release version 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
devanych committed Jul 21, 2020
1 parent 613e8b8 commit e297eef
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 51 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
# Devanych Di Container Change Log

## 2.0.0 - under development
## 2.0.0 - 2020-07-21

### Added

- `Devanych\Di\FactoryInterface`.
- `vimeo/psalm` package for static analysis code.
- Add a `build` action that is triggered when `push` and `pull_request` events.
- `build` action that is triggered when `push` and `pull_request` events.

### Changed

- Increases the minimum supported PHP version to 7.4.
- Updates package dependencies to composer.json.
- PSR-2 coding standard on PSR-12.
- Modifies `Devanych\Di\Container`:
- Adds `__construct(array $definitions = [])` method; inside the constructor calls the `setAll()` method.
- Adds `__construct(array $definitions = [])` method; inside the constructor calls the `setMultiple()` method.
- Adds automatic resolving `Devanych\Di\FactoryInterface` instances to the `Container::get()` and `Container::getNew()` methods.
- Replaces deprecated reflection methods (`ReflectionParameter::getClass()` and `ReflectionParameter::isArray()`) to usage `ReflectionNamedType` for PHP 8.0.
- Renames `setAll()` to `setMultiple()` method.
- Makes the class is final.

### Deprecated
Expand Down
139 changes: 93 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
# Dependency Injection Container

PHP package. Implementation of a dependency injection [PSR-11 Container](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md).
[![License](https://poser.pugx.org/devanych/di-container/license)](https://packagist.org/packages/devanych/di-container)
[![Latest Stable Version](https://poser.pugx.org/devanych/di-container/v)](https://packagist.org/packages/devanych/di-container)
[![Total Downloads](https://poser.pugx.org/devanych/di-container/downloads)](https://packagist.org/packages/devanych/di-container)
[![GitHub Build Status](https://github.com/devanych/di-container/workflows/build/badge.svg)](https://github.com/devanych/di-container/actions)
[![Scrutinizer Code Coverage](https://scrutinizer-ci.com/g/devanych/di-container/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/devanych/di-container/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/devanych/di-container/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/devanych/di-container/?branch=master)

Simple and lightweight container using autowiring.

This package requires PHP version 7.2 or later.
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
* Objects or class names.

* Anonymous functions (Closure instance).

* anonymous functions (Closure instance)
* Scalars (integer, float, string, boolean).

* scalars (integer, float, string, boolean)
* Arrays and nested arrays with all of the above data types.

* 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 library is installed using the composer:
This package requires PHP version 7.4 or later.

```
composer require devanych/di-container
Expand All @@ -32,9 +37,11 @@ Create a container:
use Devanych\Di\Container;

$container = new Container();
// or with definitions array
$container = new Container($definitions);
```

Sets in container:
Sets in the container:

```php
/**
Expand All @@ -46,26 +53,26 @@ Sets in container:
$container->set($id, $definition);

/**
* Sets multiple definitions at once.
* Sets multiple definitions at once; used in the constructor.
*
* @param array $definitions
* @param array<string, mixed> $definitions
*/
$container->setAll($definitions);
$container->setMultiple($definitions);
```

Has in container:
Existence in the container:

```php
/**
* Returns `true` if the container can return an definition for this ID, otherwise `false`.
* Returns 'true` if the dependency with this ID was sets, otherwise `false`.
*
* @param string $id
* @return bool
*/
$container->has($id);
```

Gets from container:
Gets from the container:

```php
/**
Expand Down Expand Up @@ -97,35 +104,32 @@ $container->getNew($id);
*/
$container->getDefinition($id);
```
If the definition is an anonymous function or class name, the `get()` method will run the function and create an instance of the class only the first time, and subsequent `get()` calls will return the result already created.
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 run the function and create an instance of the class every time, use the `getNew()` method.
> 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, the object will still be created as if it had been set.
> 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

Simplest use:
Simple usage:

```php
// Set string
$container->set('string', 'value');
// Result: 'value'
$container->get('string');
$container->get('string'); // 'value'

// Set integer
$container->set('integer', 5);
// Result: 5
$container->get('integer');
$container->get('integer'); // 5

// Set array
$container->set('array', [1,2,3]);
// Result: [1,2,3]
$container->get('array');
$container->get('array'); // [1,2,3]

// Set nested array
$container->set('nested', [
Expand All @@ -136,17 +140,15 @@ $container->set('nested', [
'string' => 'string',
],
'not_scalar' => [
'closure' => function () {return;},
'closure' => fn() => null,
'object' => new User(),
'array' => ['array'],
],
]);

// Set object
$container->set('user', function () {
return new User();
});
$container->get('user');
$container->set('user', fn() => new User());
$container->get('user'); // User instance
// Or
$container->set('user', User::class);
$container->get('user');
Expand All @@ -157,37 +159,37 @@ $container->get(User::class);
$container->get(User::class);
```

Use with dependencies:
Usage of dependencies:

```php
/*
class User
final class UserProfile
{
private $profile;
private $name;
private $age;

public function __construct(UserProfile $profile)
public function __construct(string $name = 'John', int $age = 25)
{
$this->profile = $profile;
$this->name = $name;
$this->age = $age;
}
}

class UserProfile
final class User
{
private $name;
private $age;
private $profile;

public function __construct(string $name = 'John', int $age = 25)
public function __construct(UserProfile $profile)
{
$this->name = $name;
$this->age = $age;
$this->profile = $profile;
}
}
*/

$container->set('user_name', 'Alexander');
$container->set('user_age', 40);

$container->set('user', function (\Psr\Container\ContainerInterface $container) {
$container->set('user', function (\Psr\Container\ContainerInterface $container): User {
$name = $container->get('user_name');
$age = $container->get('user_age');
$profile = new UserProfile($name, $age);
Expand All @@ -198,11 +200,11 @@ $container->get('user');

// Or

$container->set(UserProfile::class, function (\Psr\Container\ContainerInterface $container) {
$container->set(UserProfile::class, function (\Psr\Container\ContainerInterface $container): UserProfile {
return new UserProfile($container->get('user_name'), $container->get('user_age'));
});

$container->set(User::class, function ($container) {
$container->set(User::class, function (\Psr\Container\ContainerInterface $container): User {
return new User($container->get(UserProfile::class));
});

Expand All @@ -212,4 +214,49 @@ $container->get(User::class);

$container->set(User::class, User::class);
$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'));
}
}

final class UserFactory implements \Devanych\Di\FactoryInterface
{
public ?string $name;
public ?int $age;

public function __construct(string $name = null, int $age = null)
{
$this->name = $name;
$this->age = $age;
}

public function create(\Psr\Container\ContainerInterface $container): User
{
if ($this->name === null || $this->age === null) {
return new User($container->get(UserProfile::class));
}

return new User(new UserProfile($this->name, $this->age));
}
}
*/

$container->setMultiple([
'user_name' => 'Alexander',
'user_age' => 40,
User::class => UserFactory::class,
UserProfile::class => UserProfileFactory::class,
]);

$container->get(User::class); // User instance
$container->get(UserProfile::class); // UserProfile instance
```
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "devanych/di-container",
"description": "PSR-11 dependency injection container implementation",
"description": "Simple implementation of a PSR-11 dependency injection container",
"keywords": ["php", "di", "container", "psr-11", "autowiring", "autowire"],
"type": "library",
"license": "MIT",
Expand All @@ -17,7 +17,7 @@
"source": "https://github.com/devanych/di-container"
},
"require": {
"php": ">=7.4",
"php": "^7.4",
"psr/container": "^1.0"
},
"require-dev": {
Expand Down

0 comments on commit e297eef

Please # to comment.