diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index eeaaffad4d..b001026a19 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -34,6 +34,7 @@ Yii Framework 2 Change Log - Enh #15221: Improved the `help/list-action-options` console command output for command options without a description (brandonkelly) - Enh #15332: Always check for availability of `openssl_pseudo_random_bytes`, even if LibreSSL is available (sammousa) - Enh #15335: Added `FileHelper::unlink()` that works well under all OSes (samdark) +- Enh #15347: Add `Instance` support for object property in DI container (kojit2009) - Enh #15340: Test CHANGELOG.md for valid format (sammousa) - Enh #15360: Refactored `BaseConsole::updateProgress()` (developeruz) - Bug #15317: Regenerate CSRF token if an empty value is given (sammousa) diff --git a/framework/di/Container.php b/framework/di/Container.php index 2181a78681..61fa6910b3 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -375,6 +375,8 @@ class Container extends Component return $reflection->newInstanceArgs($dependencies); } + $config = $this->resolveDependencies($config); + if (!empty($dependencies) && $reflection->implementsInterface('yii\base\Configurable')) { // set $config as the last parameter (existing one will be overwritten) $dependencies[count($dependencies) - 1] = $config; diff --git a/tests/framework/di/ContainerTest.php b/tests/framework/di/ContainerTest.php index 8f413f6d47..6b652caa07 100644 --- a/tests/framework/di/ContainerTest.php +++ b/tests/framework/di/ContainerTest.php @@ -15,7 +15,9 @@ use yiiunit\data\ar\Cat; use yiiunit\data\ar\Order; use yiiunit\data\ar\Type; use yiiunit\framework\di\stubs\Bar; +use yiiunit\framework\di\stubs\BarSetter; use yiiunit\framework\di\stubs\Foo; +use yiiunit\framework\di\stubs\FooProperty; use yiiunit\framework\di\stubs\Qux; use yiiunit\framework\di\stubs\QuxInterface; use yiiunit\TestCase; @@ -95,6 +97,19 @@ class ContainerTest extends TestCase $this->assertInstanceOf($Bar, $foo->bar); $this->assertInstanceOf($Qux, $foo->bar->qux); + // predefined property parameters + $fooSetter = FooProperty::className(); + $barSetter = BarSetter::className(); + + $container = new Container(); + $container->set('foo', ['class' => $fooSetter, 'bar' => Instance::of('bar')]); + $container->set('bar', ['class' => $barSetter, 'qux' => Instance::of('qux')]); + $container->set('qux', $Qux); + $foo = $container->get('foo'); + $this->assertInstanceOf($fooSetter, $foo); + $this->assertInstanceOf($barSetter, $foo->bar); + $this->assertInstanceOf($Qux, $foo->bar->qux); + // wiring by closure $container = new Container(); $container->set('qux', new Qux()); diff --git a/tests/framework/di/stubs/BarSetter.php b/tests/framework/di/stubs/BarSetter.php new file mode 100644 index 0000000000..355d41d049 --- /dev/null +++ b/tests/framework/di/stubs/BarSetter.php @@ -0,0 +1,40 @@ + + * @since 2.0 + * + * @property QuxInterface $qux + */ +class BarSetter extends BaseObject +{ + /** + * @var QuxInterface + */ + private $qux; + + /** + * @return QuxInterface + */ + public function getQux() + { + return $this->qux; + } + + /** + * @param mixed $qux + */ + public function setQux(QuxInterface $qux) + { + $this->qux = $qux; + } +} diff --git a/tests/framework/di/stubs/FooProperty.php b/tests/framework/di/stubs/FooProperty.php new file mode 100644 index 0000000000..022d2e3729 --- /dev/null +++ b/tests/framework/di/stubs/FooProperty.php @@ -0,0 +1,24 @@ + + * @since 2.0 + * + * @property BarSetter $bar + */ +class FooProperty extends BaseObject +{ + /** + * @var BarSetter + */ + public $bar; +}