A slim, PSR 11, framework-agnostic DI container

v2.0.0 2022-01-23 17:56 UTC

This package is auto-updated.

Last update: 2022-04-23 18:47:24 UTC


README

EDICT (Easy DI ConTainer) is a slim, PSR 11, framework-agnostic dependency injection container.

Cool features:

  • Autowiring support (can be toggled off)
  • PHP attributes support
  • 100% tested and documented
  • Uses an up-to-date PHP version

About

Info Value
Current version Packagist Version
Requires PHP from Packagist
License Packagist
Tests Build Status
Code coverage Code Coverage
Tested with phpunit, phan, psalm, phpcs, phpstan, infection

Installation

composer require ingenioz-it/edict

How to use

To use Edict, put the following line into your code:

$edict = new \IngeniozIT\Edict\Container();

Edict is now ready to go. Yes, it's that simple !

Types of entries

Depending on your needs, you can create several types of entries:

Simple values

Scalar, arrays, objects ... pretty much whatever you want.

use function IngeniozIT\Edict\value;

$edict->set('entryName', value('entryValue'));

$edict->get('entryName'); // 'entryValue'

Aliases

Maps an entry to another entry.

use function IngeniozIT\Edict\alias;

$edict->set('entryName', value(42));
$edict->set('aliasEntryName', alias('entryName'));

$edict->get('aliasEntryName'); // 42

Dynamic values

These entries will be resolved everytime you call them.

use function IngeniozIT\Edict\dynamic;

$edict->set('entryName', dynamic(fn() => date('H:i:s')));

$edict->get('entryName'); // '08:36:51'
sleep(1);
$edict->get('entryName'); // '08:36:52' <-- one second has passed

Lazy loaded values

These entries will be resolved only once. Use them when you want to use the same object across your application (like a database handle).

use function IngeniozIT\Edict\lazyload;

$edict->set('entryName', lazyload(fn() => new PDO(/* ... */)));

$edict->get('entryName'); // Your PDO instance
$edict->get('entryName'); // The same PDO instance

Plain entry

These entries will return the result of the callback you give them. Use them for advanced injections.

use function IngeniozIT\Edict\entry;

$edict->set('entryName', entry(fn() => 42));

$edict->get('entryName'); // 42

Setting multiple entries at once

You can set multiple entries at once:

$edict->setMany([
    'entry1' => value('foo'),
    'entry2' => value('bar'),
    'entry3' => alias('someEntry'),
]);

Using the container inside an entry

You can use the container inside the callback to fetch other entries.

use Psr\Container\ContainerInterface;

// Put this inside a local config file.
$edict->setMany([
    'db.dsn' => value('mysql:dbname=mydb;host=localhost'),
    'db.username' => value('root'),
    'db.password' => value('secret'),
);

// To instantiate the db
$edict->set('database', lazyload(
    fn(ContainerInterface $container) => new PDO(
        $container->get('db.dsn'),
        $container->get('db.username'),
        $container->get('db.password')
    ))
);

$edict->get('database'); // Your PDO object

Autowiring

Edict can use autowiring to automatically resolve dependencies and instantiate your classes:

class MyClass
{
}

$edict->get(MyClass::class); // Instance of MyClass, no configuration needed

Edict will inject any dependency for you, as long as it can be resolved:

class AnotherClass
{
    public function __construct(MyClass $class) { /*...*/ }
}

$edict->get(AnotherClass::class); // Instance of AnotherClass

You can disable/enable autowiring anytime you want. Any class that has already been autowired will still be accessible.

$edict->disableAutowiring();
$edict->enableAutowiring();

PHP Attributes

Some parameters cannot be automatically resolved. You can either create your own entry to pass the correct values to the constructor, or you can use a PHP attribute to tell Edict which entry to use:

use IngeniozIT\Edict\Inject;

class MyClass
{
    public function __construct(
        #[Inject('entryToInject')] int $value
    ) {
        /*...*/
    }
}

$edict->set('entryToInject', value(42));

$edict->get(MyClass::class); // Instance of MyClass with $value = 42

Full documentation

You can list the available features by running

composer testdox

The corresponding code samples are located in the unit tests file.