Skip to content

Commit 3506f34

Browse files
[DI] Add ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE
1 parent b9fc357 commit 3506f34

File tree

9 files changed

+34
-11
lines changed

9 files changed

+34
-11
lines changed

src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,21 @@ class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass
2424
{
2525
protected function processValue($value, $isRoot = false)
2626
{
27-
if ($value instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
28-
$destId = (string) $value;
27+
if (!$value instanceof Reference) {
28+
return parent::processValue($value, $isRoot);
29+
}
30+
31+
switch ($value->getInvalidBehavior()) {
32+
case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE:
33+
case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE:
34+
$destId = (string) $value;
2935

30-
if (!$this->container->has($destId)) {
31-
throw new ServiceNotFoundException($destId, $this->currentId);
32-
}
36+
if (!$this->container->has($destId)) {
37+
throw new ServiceNotFoundException($destId, $this->currentId);
38+
}
39+
break;
3340
}
3441

35-
return parent::processValue($value, $isRoot);
42+
return $value;
3643
}
3744
}

src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ protected function processValue($value, $isRoot = false)
7474
if ($optionalBehavior = '?' === $type[0]) {
7575
$type = substr($type, 1);
7676
$optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
77+
} elseif ($optionalBehavior = '!' === $type[0]) {
78+
$type = substr($type, 1);
79+
$optionalBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
7780
}
7881
if (is_int($key)) {
7982
$key = $type;

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* * NULL_ON_INVALID_REFERENCE: Returns null
4444
* * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
4545
* (for instance, ignore a setter if the service does not exist)
46+
* * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for existing but uninitialized services
4647
*
4748
* @author Fabien Potencier <fabien@symfony.com>
4849
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
@@ -304,9 +305,9 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
304305

305306
try {
306307
if (isset($this->fileMap[$id])) {
307-
return $this->load($this->fileMap[$id]);
308+
return self::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
308309
} elseif (isset($this->methodMap[$id])) {
309-
return $this->{$this->methodMap[$id]}();
310+
return self::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
310311
} elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
311312
$id = $normalizedId;
312313
continue;
@@ -328,7 +329,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
328329
}
329330
}
330331

331-
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
332+
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior || self::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) {
332333
if (!$id) {
333334
throw new ServiceNotFoundException($id);
334335
}

src/Symfony/Component/DependencyInjection/ContainerInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface ContainerInterface extends PsrContainerInterface
2727
const EXCEPTION_ON_INVALID_REFERENCE = 1;
2828
const NULL_ON_INVALID_REFERENCE = 2;
2929
const IGNORE_ON_INVALID_REFERENCE = 3;
30+
const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;
3031

3132
/**
3233
* Sets a service.

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ private function convertParameters(array $parameters, $type, \DOMElement $parent
309309
$element->setAttribute('on-invalid', 'null');
310310
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
311311
$element->setAttribute('on-invalid', 'ignore');
312+
} elseif ($behaviour == ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE) {
313+
$element->setAttribute('on-invalid', 'ignore_uninitialized');
312314
}
313315
} elseif ($value instanceof Definition) {
314316
$element->setAttribute('type', 'service');

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,11 @@ private function dumpValue($value)
304304
*/
305305
private function getServiceCall($id, Reference $reference = null)
306306
{
307-
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
308-
return sprintf('@?%s', $id);
307+
if (null !== $reference) {
308+
switch ($reference->getInvalidBehavior()) {
309+
case ContainerInterface::IGNORE_ON_INVALID_REFERENCE: return sprintf('@?%s', $id);
310+
case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: return sprintf('@!%s', $id);
311+
}
309312
}
310313

311314
return sprintf('@%s', $id);

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $file, $lowercase =
492492
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
493493
if ('ignore' == $onInvalid) {
494494
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
495+
} elseif ('ignore_uninitialized' == $onInvalid) {
496+
$invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
495497
} elseif ('null' == $onInvalid) {
496498
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
497499
}

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,9 @@ private function resolveServices($value, $file, $isParameter = false)
758758
if (0 === strpos($value, '@@')) {
759759
$value = substr($value, 1);
760760
$invalidBehavior = null;
761+
} elseif (0 === strpos($value, '@!')) {
762+
$value = substr($value, 2);
763+
$invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
761764
} elseif (0 === strpos($value, '@?')) {
762765
$value = substr($value, 2);
763766
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;

src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@
266266
<xsd:enumeration value="null" />
267267
<xsd:enumeration value="ignore" />
268268
<xsd:enumeration value="exception" />
269+
<xsd:enumeration value="ignore_uninitialized" />
269270
</xsd:restriction>
270271
</xsd:simpleType>
271272

0 commit comments

Comments
 (0)