Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Better ServiceLocatorAwareInterface duck typing
Browse files Browse the repository at this point in the history
Do not check if ServiceLocatorAwareInterface exists, as that will skip
the initializer when it does, but the instance does not implement it and
*does* fit duck typing rules.
  • Loading branch information
weierophinney committed Feb 29, 2016
1 parent c4d7430 commit 99e4212
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 6 deletions.
8 changes: 6 additions & 2 deletions src/Controller/ControllerManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ public function __construct($configOrContainerInstance, array $v3config = [])
$this->addInitializer([$this, 'injectEventManager']);
$this->addInitializer([$this, 'injectConsole']);
$this->addInitializer([$this, 'injectPluginManager']);
$this->addInitializer([$this, 'injectServiceLocator']);
parent::__construct($configOrContainerInstance, $v3config);

// Added after parent construction, as v2 abstract plugin managers add
// one during construction.
$this->addInitializer([$this, 'injectServiceLocator']);
}

/**
Expand Down Expand Up @@ -204,6 +207,7 @@ public function injectPluginManager($first, $second)
*/
public function injectServiceLocator($first, $second)
{
printf("In %s\n", __METHOD__);
if ($first instanceof ContainerInterface) {
$container = $first;
$controller = $second;
Expand All @@ -217,7 +221,7 @@ public function injectServiceLocator($first, $second)
$container = $container->getServiceLocator() ?: $container;
}

if (! interface_exists(ServiceLocatorAwareInterface::class)
if (! $controller instanceof ServiceLocatorAwareInterface
&& method_exists($controller, 'setServiceLocator')
) {
trigger_error(sprintf(
Expand Down
2 changes: 1 addition & 1 deletion src/Service/ServiceManagerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public function __construct(array $config = [])
$instance->setServiceLocator($container);
}

if (! interface_exists(ServiceLocatorAwareInterface::class)
if (! $instance instanceof ServiceLocatorAwareInterface

This comment has been minimized.

Copy link
@dymen1

dymen1 Mar 2, 2016

Hi, this statement now throws an error when a class doesn't implement ServiceLocatorAwareInterface and has the method setServiceLocator. Resulting in a confusing error.

This comment has been minimized.

Copy link
@froschdesign

froschdesign Mar 2, 2016

Member

See #87

&& method_exists($instance, 'setServiceLocator')
) {
trigger_error(sprintf(
Expand Down
6 changes: 3 additions & 3 deletions test/Service/ServiceManagerConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@ public function testEventManagerInitializerCanBeReplaced()

public function testServiceLocatorAwareInitializerInjectsDuckTypedImplementations()
{
$serviceManager = new ServiceManager(['factories' => [
$serviceManager = new ServiceManager();
(new ServiceManagerConfig(['factories' => [
TestAsset\DuckTypedServiceLocatorAware::class => InvokableFactory::class,
]]);
(new ServiceManagerConfig())->configureServiceManager($serviceManager);
]]))->configureServiceManager($serviceManager);

$instance = $serviceManager->get(TestAsset\DuckTypedServiceLocatorAware::class);
$this->assertInstanceOf(TestAsset\DuckTypedServiceLocatorAware::class, $instance);
Expand Down

0 comments on commit 99e4212

Please sign in to comment.