Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Di Laravel Package

aura/di

Aura.Di is a PSR-11 dependency injection container for PHP 8+, supporting serializable containers, constructor and setter injection, interface/trait awareness, and configuration inheritance. Lightweight, standards-friendly, and flexible for complex apps.

View on GitHub
Deep Wiki
Context7

Contextual Injection

There are scenarios in which you may want to change the injecting object based on the object that is being constructed. This is called contextual injection. There are two solutions to this problem. The following two examples should make clear which solution is preferable for a problem.

Example: four levels deep

An example could be a logger class that you inject into a database connection class. If the connection class is injected to a console application class, you want to inject a plain text logger. In case the connection is injected to a web application class, you may want to inject a Redis logger. The connection class itself requires a config class, that in its turn requires the logger class.

Solution 1: pass overwriting params to the lazyNew method.

// define the default situation
$di->params['Vendor\Package\ConsoleApplication']['database'] = $di->lazyNew('Vendor\Package\DatabaseConnection');
$di->params['Vendor\Package\DatabaseConnection']['config'] = $di->lazyNew('Vendor\Package\Config');
$di->params['Vendor\Package\Config']['logger'] = $di->lazyNew('Vendor\Package\PlainTextLogger');
$di->params['Vendor\Package\PlainTextLogger']['param1'] = 'value1';

// define the web application context
$di->params['Vendor\Package\RedisLogger']['username'] = 'a';
$di->params['Vendor\Package\RedisLogger']['password'] = 'b';
$di->params['Vendor\Package\RedisLogger']['host'] = 'c';
$di->params['Vendor\Package\WebApplication']['config'] = $di->lazyNew('Vendor\Package\DatabaseConnection', [
    'config' => $di->lazyNew(Config::class, [
        'logger' => $di->lazyNew(RedisLogger::class)
    ])
]);

This solution also works with newInstance.

Solution 2: contextual parameters

For this problem there is also another solution. You can pass a withContext to the lazyNew method for the database connection injection into the web application class.

// define the default situation
$di->params['Vendor\Package\ConsoleApplication']['database'] = $di->lazyNew('Vendor\Package\DatabaseConnection');
$di->params['Vendor\Package\DatabaseConnection']['config'] = $di->lazyNew('Vendor\Package\Config');
$di->params['Vendor\Package\Config']['logger'] = $di->lazyNew('Vendor\Package\PlainTextLogger');
$di->params['Vendor\Package\PlainTextLogger']['param1'] = 'value1';

// define the web application context
$di->params['Vendor\Package\RedisLogger']['username'] = 'a';
$di->params['Vendor\Package\RedisLogger']['password'] = 'b';
$di->params['Vendor\Package\RedisLogger']['host'] = 'c';
$di->params['Vendor\Package\WebApplication']['config'] = $di->lazyNew('Vendor\Package\DatabaseConnection')
    ->withContext(new Blueprint(Config::class, [
        'logger' => $di->lazyNew(RedisLogger::class)
    ]));

This solution does not work with newInstance.

Example, five levels deep

The latter solution becomes more preferable to the former when the context of the dependency tree becomes larger and larger, because in the latter solution one does not need to know the complete dependency tree. This is clear in the following scenario. Suppose the console and the web application both require the Redis logger, but with different parameters (e.g. different host name).

Then we can have the following two solutions.

Solution based on overwriting params

// define the default situation
$di->params['Vendor\Package\ConsoleApplication']['database'] = $di->lazyNew('Vendor\Package\DatabaseConnection');
$di->params['Vendor\Package\DatabaseConnection']['config'] = $di->lazyNew('Vendor\Package\Config');
$di->params['Vendor\Package\Config']['logger'] = $di->lazyNew('Vendor\Package\RedisLogger');
$di->params['Vendor\Package\RedisLogger']['username'] = 'x';
$di->params['Vendor\Package\RedisLogger']['password'] = 'y';
$di->params['Vendor\Package\RedisLogger']['host'] = 'z';

// define the web application context
$di->params['Vendor\Package\WebApplication']['config'] = $di->lazyNew('Vendor\Package\DatabaseConnection', [
    'config' => $di->lazyNew(Config::class, [
        'logger' => $di->lazyNew(RedisLogger::class, [
            'username' => 'a'
            'password' => 'b'
            'host' => 'c'
        ])
    ])
]);

As becomes very clear here, the overwriting context of the web application requires defining the complete tree to the change the username, password and host parameters.

Solution based on contextual params

// define the default situation
$di->params['Vendor\Package\ConsoleApplication']['database'] = $di->lazyNew('Vendor\Package\DatabaseConnection');
$di->params['Vendor\Package\DatabaseConnection']['config'] = $di->lazyNew('Vendor\Package\Config');
$di->params['Vendor\Package\Config']['logger'] = $di->lazyNew('Vendor\Package\RedisLogger');
$di->params['Vendor\Package\RedisLogger']['username'] = 'x';
$di->params['Vendor\Package\RedisLogger']['password'] = 'y';
$di->params['Vendor\Package\RedisLogger']['host'] = 'z';

// define the web application context
$di->params['Vendor\Package\WebApplication']['config'] = $di->lazyNew('Vendor\Package\DatabaseConnection')
    ->withContext(new Blueprint(RedisLogger::class, [
         'username' => 'a'
         'password' => 'b'
         'host' => 'c'
     ]));

Here you can see that whenever WebApplication requires a Redis logger through the database connection, it passes different values and there is no need to define the whole dependency tree again.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport