From 5262831fdf52d9bff9ee8bfb884e0ad814eeda76 Mon Sep 17 00:00:00 2001 From: Ivan Vegner Date: Wed, 2 Aug 2017 12:31:26 +0300 Subject: [PATCH] Add auto declarer interface to allow mixing auto dependencies and manual dependencies --- src/AutoDeclarerInterface.php | 9 +++++++ ...DeclareTrait.php => AutoDeclarerTrait.php} | 4 ++-- src/Container.php | 24 ++++++++++++------- src/ProviderInterface.php | 2 +- tests/AutoDeclareService.php | 15 ------------ tests/AutoDeclarerService.php | 15 ++++++++++++ ...raitTest.php => AutoDeclarerTraitTest.php} | 6 ++--- tests/ContainerTest.php | 2 +- tests/LegacyProvider.php | 13 +++++----- 9 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 src/AutoDeclarerInterface.php rename src/{AutoDeclareTrait.php => AutoDeclarerTrait.php} (85%) delete mode 100644 tests/AutoDeclareService.php create mode 100644 tests/AutoDeclarerService.php rename tests/{AutoDeclareTraitTest.php => AutoDeclarerTraitTest.php} (66%) diff --git a/src/AutoDeclarerInterface.php b/src/AutoDeclarerInterface.php new file mode 100644 index 0000000..b21b829 --- /dev/null +++ b/src/AutoDeclarerInterface.php @@ -0,0 +1,9 @@ +getDefaultProperties () as $name => $value) { diff --git a/src/Container.php b/src/Container.php index 14ca0cc..dbdac46 100644 --- a/src/Container.php +++ b/src/Container.php @@ -14,7 +14,7 @@ public function __construct(array $config = [], $selfName = '') { } public function connect(ProviderInterface $provider) { - $this->initializers[$provider->getName()] = function () use ($provider) { + $this->initializers[$provider->getServiceName()] = function () use ($provider) { $this->inject($provider); return $provider->provide(); }; @@ -55,9 +55,7 @@ public function inject($consumer) { $parameters = $this->getParameterValues(new \ReflectionFunction($consumer)); return $consumer(...$parameters); } else { - if ($consumer instanceof DeclarerInterface) { - $consumer = $this->injectDeclared($consumer); - } + $consumer = $this->injectDeclarer($consumer); return $consumer; } } @@ -83,14 +81,22 @@ private function produceRecursive($initializer, array $names) { } else { $instance = $initializer; } - if ($instance instanceof DeclarerInterface) { - $instance = $this->injectDeclared($instance); - } + $instance = $this->injectDeclarer($instance); return $instance; } - private function injectDeclared(DeclarerInterface $object) { - foreach ($object->declareDependencies() as $name) { + private function injectDeclarer($object) { + if ($object instanceof AutoDeclarerInterface) { + $object = $this->injectByNames($object, $object->autoDeclareDependencies()); + } + if ($object instanceof DeclarerInterface) { + $object = $this->injectByNames($object, $object->declareDependencies()); + } + return $object; + } + + private function injectByNames($object, array $names) { + foreach ($names as $name) { $setter = 'set' . implode('', array_map('ucfirst', explode('_', $name))); if (!method_exists($object, $setter)) { throw new Exception("Object declared $name dependency, but setter method $setter was not found"); diff --git a/src/ProviderInterface.php b/src/ProviderInterface.php index cfed00c..1b50cb9 100644 --- a/src/ProviderInterface.php +++ b/src/ProviderInterface.php @@ -2,6 +2,6 @@ namespace SD\DependencyInjection; interface ProviderInterface { - public function getName(): string; + public function getServiceName(): string; public function provide(); } diff --git a/tests/AutoDeclareService.php b/tests/AutoDeclareService.php deleted file mode 100644 index 50279fc..0000000 --- a/tests/AutoDeclareService.php +++ /dev/null @@ -1,15 +0,0 @@ -container; - } -} diff --git a/tests/AutoDeclarerService.php b/tests/AutoDeclarerService.php new file mode 100644 index 0000000..f6feeb6 --- /dev/null +++ b/tests/AutoDeclarerService.php @@ -0,0 +1,15 @@ +container; + } +} diff --git a/tests/AutoDeclareTraitTest.php b/tests/AutoDeclarerTraitTest.php similarity index 66% rename from tests/AutoDeclareTraitTest.php rename to tests/AutoDeclarerTraitTest.php index 754b5e7..e089905 100644 --- a/tests/AutoDeclareTraitTest.php +++ b/tests/AutoDeclarerTraitTest.php @@ -2,13 +2,13 @@ namespace tests; use PHPUnit\Framework\TestCase; -use SD\DependencyInjection\AutoDeclareTrait; +use SD\DependencyInjection\AutoDeclarerTrait; use SD\DependencyInjection\Container; -class AutoDeclareTraitTest extends TestCase { +class AutoDeclarerTraitTest extends TestCase { public function testDeclareDependencies() { $container = new Container([], 'container'); - $service = $container->produce(AutoDeclareService::class); + $service = $container->produce(AutoDeclarerService::class); $this->assertEquals($container, $service->getContainer(), 'Must inject container with auto declare'); } } diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 487925c..8f33c25 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -60,7 +60,7 @@ public function testConnect() { ); $provider = new LegacyProvider(); $container->connect($provider); - $service = $container->get($provider->getName()); + $service = $container->get($provider->getServiceName()); $this->assertInstanceOf(LegacyService::class, $service, 'Must return instance of LegacyService'); $this->assertEquals($name, $service->getName(), 'Must inject name from config'); $this->assertEquals($container, $service->getContainer(), 'Must inject container by setter'); diff --git a/tests/LegacyProvider.php b/tests/LegacyProvider.php index b47a42c..52d6e3e 100644 --- a/tests/LegacyProvider.php +++ b/tests/LegacyProvider.php @@ -1,28 +1,27 @@ autoDeclareDependencies(), ['name']); + return ['name']; } public function setName(string $name) { $this->name = $name; } - public function getName(): string { + public function getServiceName(): string { return 'helloWorld'; }