Skip to content

Commit

Permalink
Allow users to specify configuration keys to be used for primitive bi…
Browse files Browse the repository at this point in the history
…nding

Syntactic sugar around fancy calls to `->give()`.

```
$container
    ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
    ->needs('$username')
    ->giveConfig('test.username');
```

Is the same as:

```
$container
    ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
    ->needs('$username')
    ->give(function () {
        return config('test.username');
    });
```

and

```
$container
    ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
    ->needs('$username')
    ->give(fn() => config('test.username'));
```
  • Loading branch information
simensen committed Feb 12, 2021
1 parent 5ab3464 commit 20a5688
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/Illuminate/Container/ContextualBindingBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,20 @@ public function giveTagged($tag)
return is_array($taggedServices) ? $taggedServices : iterator_to_array($taggedServices);
});
}

/**
* Define configuration key to be used to look up in configuration to bind as a primitive.
*
* @param string $key
* @param ?string $default
* @return void
*/
public function giveConfig($key, $default = null)
{
$this->give(function ($container) use ($key, $default) {
$config = $container->get('config');

return $config->get($key, $default);
});
}
}
146 changes: 146 additions & 0 deletions tests/Container/ContextualBindingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Tests\Container;

use Illuminate\Config\Repository;
use Illuminate\Container\Container;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -359,6 +360,127 @@ public function testContextualBindingGivesTagsForVariadic()
$this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
$this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
}

public function testContextualBindingGivesValuesFromConfigOptionalValueNull()
{
$container = new Container;

$container->singleton('config', function () {
return new Repository([
'test' => [
'username' => 'laravel',
'password' => 'hunter42',
],
]);
});

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$username')
->giveConfig('test.username');

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$password')
->giveConfig('test.password');

$resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);

$this->assertEquals('laravel', $resolvedInstance->username);
$this->assertEquals('hunter42', $resolvedInstance->password);
$this->assertNull($resolvedInstance->alias);
}

public function testContextualBindingGivesValuesFromConfigOptionalValueSet()
{
$container = new Container;

$container->singleton('config', function () {
return new Repository([
'test' => [
'username' => 'laravel',
'password' => 'hunter42',
'alias' => 'lumen',
],
]);
});

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$username')
->giveConfig('test.username');

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$password')
->giveConfig('test.password');

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$alias')
->giveConfig('test.alias');

$resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);

$this->assertEquals('laravel', $resolvedInstance->username);
$this->assertEquals('hunter42', $resolvedInstance->password);
$this->assertEquals('lumen', $resolvedInstance->alias);
}

public function testContextualBindingGivesValuesFromConfigWithDefault()
{
$container = new Container;

$container->singleton('config', function () {
return new Repository([
'test' => [
'password' => 'hunter42',
],
]);
});

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$username')
->giveConfig('test.username', 'DEFAULT_USERNAME');

$container
->when(ContainerTestContextInjectFromConfigIndividualValues::class)
->needs('$password')
->giveConfig('test.password');

$resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);

$this->assertEquals('DEFAULT_USERNAME', $resolvedInstance->username);
$this->assertEquals('hunter42', $resolvedInstance->password);
$this->assertNull($resolvedInstance->alias);
}

public function testContextualBindingGivesValuesFromConfigArray()
{
$container = new Container;

$container->singleton('config', function () {
return new Repository([
'test' => [
'username' => 'laravel',
'password' => 'hunter42',
'alias' => 'lumen',
],
]);
});

$container
->when(ContainerTestContextInjectFromConfigArray::class)
->needs('$settings')
->giveConfig('test');

$resolvedInstance = $container->make(ContainerTestContextInjectFromConfigArray::class);

$this->assertEquals('laravel', $resolvedInstance->settings['username']);
$this->assertEquals('hunter42', $resolvedInstance->settings['password']);
$this->assertEquals('lumen', $resolvedInstance->settings['alias']);
}
}

interface IContainerContextContractStub
Expand Down Expand Up @@ -474,3 +596,27 @@ public function __construct(ContainerContextNonContractStub $other, IContainerCo
$this->stubs = $stubs;
}
}

class ContainerTestContextInjectFromConfigIndividualValues
{
public $username;
public $password;
public $alias = null;

public function __construct($username, $password, $alias = null)
{
$this->username = $username;
$this->password = $password;
$this->alias = $alias;
}
}

class ContainerTestContextInjectFromConfigArray
{
public $settings;

public function __construct($settings)
{
$this->settings = $settings;
}
}

0 comments on commit 20a5688

Please sign in to comment.