Skip to content

Commit

Permalink
Merge pull request #74 from driehle/bugfix/invokables-precedence-3.6.x
Browse files Browse the repository at this point in the history
Fix invokables merging precedence in `3.6.x`
  • Loading branch information
Ocramius authored Jan 17, 2021
2 parents 7f42181 + 56da7b2 commit e730a58
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/ServiceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,10 @@ public function configure(array $config)
}

if (isset($config['invokables']) && ! empty($config['invokables'])) {
$this->createAliasesAndFactoriesForInvokables($config['invokables']);
$newAliases = $this->createAliasesAndFactoriesForInvokables($config['invokables']);
// override existing aliases with those created by invokables to ensure
// that they are still present after merging aliases later on
$config['aliases'] = $newAliases + ($config['aliases'] ?? []);
}

if (isset($config['factories'])) {
Expand Down Expand Up @@ -775,16 +778,21 @@ private function mergeDelegators(array $config): array
*
* If an invokable service name does not match the class it maps to, this
* creates an alias to the class (which will later be mapped as an
* invokable factory).
* invokable factory). The newly created aliases will be returned as an array.
*/
private function createAliasesAndFactoriesForInvokables(array $invokables): void
private function createAliasesAndFactoriesForInvokables(array $invokables): array
{
$newAliases = [];

foreach ($invokables as $name => $class) {
$this->factories[$class] = Factory\InvokableFactory::class;
if ($name !== $class) {
$this->aliases[$name] = $class;
$newAliases[$name] = $class;
}
}

return $newAliases;
}

/**
Expand Down
23 changes: 23 additions & 0 deletions test/CommonServiceLocatorBehaviorsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,29 @@ public function testConfigureCanOverridePreviousSettings()
$newServiceManager->get(DateTime::class);
}

public function testConfigureInvokablesTakePrecedenceOverFactories()
{
$firstFactory = $this->getMockBuilder(FactoryInterface::class)
->getMock();

$serviceManager = $this->createContainer([
'aliases' => [
'custom_alias' => DateTime::class,
],
'factories' => [
DateTime::class => $firstFactory,
],
'invokables' => [
'custom_alias' => stdClass::class,
],
]);

$firstFactory->expects($this->never())->method('__invoke');

$object = $serviceManager->get('custom_alias');
$this->assertInstanceOf(stdClass::class, $object);
}

/**
* @group has
*/
Expand Down

0 comments on commit e730a58

Please sign in to comment.