From 20a5688e8d4e14faaa6225fcaef4c9b6adb30ac1 Mon Sep 17 00:00:00 2001 From: Beau Simensen Date: Fri, 12 Feb 2021 09:42:01 -0600 Subject: [PATCH] Allow users to specify configuration keys to be used for primitive binding 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')); ``` --- .../Container/ContextualBindingBuilder.php | 16 ++ tests/Container/ContextualBindingTest.php | 146 ++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/src/Illuminate/Container/ContextualBindingBuilder.php b/src/Illuminate/Container/ContextualBindingBuilder.php index 5da6ccab388b..d2ff1de07984 100644 --- a/src/Illuminate/Container/ContextualBindingBuilder.php +++ b/src/Illuminate/Container/ContextualBindingBuilder.php @@ -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); + }); + } } diff --git a/tests/Container/ContextualBindingTest.php b/tests/Container/ContextualBindingTest.php index 17a7d73f00ea..1ddd5ebf8aba 100644 --- a/tests/Container/ContextualBindingTest.php +++ b/tests/Container/ContextualBindingTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Container; +use Illuminate\Config\Repository; use Illuminate\Container\Container; use PHPUnit\Framework\TestCase; @@ -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 @@ -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; + } +}