Permalink
Browse files

ContainerBuilder::addDefinition(null) adds anonymous service

  • Loading branch information...
dg committed Dec 5, 2018
1 parent 77c4efb commit f21f42bd4f7d5174582398b839486823de7d219b
@@ -175,7 +175,7 @@ public function loadDefinitions(array $services): void
$this->updateDefinition($def, $config);
}
} catch (\Exception $e) {
throw new ServiceCreationException("Service '$name': " . $e->getMessage(), 0, $e);
throw new ServiceCreationException(($name ? "Service '$name': " : '') . $e->getMessage(), 0, $e);
}
}
@@ -371,13 +371,10 @@ public function applyNamespace(array $services, string $namespace): array
}
private function createDefinitionName($name, array $config): string
private function createDefinitionName($name, array $config): ?string
{
if (is_int($name)) {
$counter = 1;
do {
$name = (string) $counter++;
} while ($this->builder->hasDefinition($name));
return null;
} elseif (preg_match('#^@[\w\\\\]+\z#', $name)) {
$name = $this->builder->getByType(substr($name, 1), true);
}
@@ -399,13 +396,13 @@ private function prepareConfig(array $config): array
}
private function retrieveDefinition(string $name, array &$config): Definitions\Definition
private function retrieveDefinition(?string $name, array &$config): Definitions\Definition
{
if (Helpers::takeParent($config)) {
$this->builder->removeDefinition($name);
}
if ($this->builder->hasDefinition($name)) {
if ($name && $this->builder->hasDefinition($name)) {
return $this->builder->getDefinition($name);
} elseif (isset($config['implement'], $config['references']) || isset($config['implement'], $config['tagged'])) {
@@ -57,25 +57,28 @@ public function __construct()
* Adds new service definition.
* @return Definitions\ServiceDefinition
*/
public function addDefinition(string $name, Definition $definition = null): Definition
public function addDefinition(?string $name, Definition $definition = null): Definition
{
$this->needsResolve = true;
if (!$name) { // builder is not ready for falsy names such as '0'
if ($name === null) {
for ($name = 1; isset($this->definitions[$name]); $name++);
$name = (string) $name;
} elseif (!$name) { // builder is not ready for falsy names such as '0'
throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($name)));
}
$name = $this->aliases[$name] ?? $name;
if (isset($this->definitions[$name])) {
throw new Nette\InvalidStateException("Service '$name' has already been added.");
}
$lname = strtolower($name);
foreach ($this->definitions as $nm => $foo) {
if ($lname === strtolower((string) $nm)) {
throw new Nette\InvalidStateException("Service '$name' has the same name as '$nm' in a case-insensitive manner.");
} else {
$name = $this->aliases[$name] ?? $name;
if (isset($this->definitions[$name])) {
throw new Nette\InvalidStateException("Service '$name' has already been added.");
}
$lname = strtolower($name);
foreach ($this->definitions as $nm => $foo) {
if ($lname === strtolower((string) $nm)) {
throw new Nette\InvalidStateException("Service '$name' has the same name as '$nm' in a case-insensitive manner.");
}
}
}
if (!$definition) {
$definition = new Definitions\ServiceDefinition;
}
$definition = $definition ?: new Definitions\ServiceDefinition;
$definition->setName($name);
$definition->setNotifier(function (): void {
$this->needsResolve = true;
@@ -84,25 +87,25 @@ public function addDefinition(string $name, Definition $definition = null): Defi
}
public function addAccessorDefinition(string $name): Definitions\AccessorDefinition
public function addAccessorDefinition(?string $name): Definitions\AccessorDefinition
{
return $this->addDefinition($name, new Definitions\AccessorDefinition);
}
public function addFactoryDefinition(string $name): Definitions\FactoryDefinition
public function addFactoryDefinition(?string $name): Definitions\FactoryDefinition
{
return $this->addDefinition($name, new Definitions\FactoryDefinition);
}
public function addLocatorDefinition(string $name): Definitions\LocatorDefinition
public function addLocatorDefinition(?string $name): Definitions\LocatorDefinition
{
return $this->addDefinition($name, new Definitions\LocatorDefinition);
}
public function addImportedDefinition(string $name): Definitions\ImportedDefinition
public function addImportedDefinition(?string $name): Definitions\ImportedDefinition
{
return $this->addDefinition($name, new Definitions\ImportedDefinition);
}
@@ -22,4 +22,4 @@ Assert::throws(function () {
setups: []
foo: bar
');
}, Nette\InvalidStateException::class, "Service '1': Unknown key 'autowire', 'setups', 'foo' in definition of service, did you mean 'autowired', 'setup'?");
}, Nette\InvalidStateException::class, "Unknown key 'autowire', 'setups', 'foo' in definition of service, did you mean 'autowired', 'setup'?");
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
use Nette\DI;
use Tester\Assert;
require __DIR__ . '/../bootstrap.php';
$builder = new DI\ContainerBuilder;
$builder->addDefinition('1')
->setFactory(stdClass::class);
$builder->addDefinition(null)
->setFactory(stdClass::class);
$builder->addDefinition(null)
->setFactory(stdClass::class);
$container = createContainer($builder);
Assert::type(stdClass::class, $container->getService('1'));
Assert::type(stdClass::class, $container->getService('2'));
Assert::type(stdClass::class, $container->getService('3'));

0 comments on commit f21f42b

Please sign in to comment.