Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 50852ed

Browse filesBrowse files
[DI] Add side-effect-restricted variant for autowiring, based solely on ids
1 parent e41064f commit 50852ed
Copy full SHA for 50852ed

File tree

10 files changed

+85
-30
lines changed
Filter options

10 files changed

+85
-30
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ private function getContainerDefinitionData(Definition $definition, $omitTags =
221221
'lazy' => $definition->isLazy(),
222222
'shared' => $definition->isShared(),
223223
'abstract' => $definition->isAbstract(),
224-
'autowire' => $definition->isAutowired(),
224+
'autowire' => $definition->isAutowired() ? (Definition::AUTOWIRE_BY_TYPE === $definition->getAutowiredBy() ? 'by-type' : 'by-id') : false,
225225
);
226226

227227
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
182182
."\n".'- Lazy: '.($definition->isLazy() ? 'yes' : 'no')
183183
."\n".'- Shared: '.($definition->isShared() ? 'yes' : 'no')
184184
."\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no')
185-
."\n".'- Autowired: '.($definition->isAutowired() ? 'yes' : 'no')
185+
."\n".'- Autowired: '.($definition->isAutowired() ? (Definition::AUTOWIRE_BY_TYPE === $definition->getAutowiredBy() ? 'by-type' : 'by-id') : 'no')
186186
;
187187

188188
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
295295
$tableRows[] = array('Lazy', $definition->isLazy() ? 'yes' : 'no');
296296
$tableRows[] = array('Shared', $definition->isShared() ? 'yes' : 'no');
297297
$tableRows[] = array('Abstract', $definition->isAbstract() ? 'yes' : 'no');
298-
$tableRows[] = array('Autowired', $definition->isAutowired() ? 'yes' : 'no');
298+
$tableRows[] = array('Autowired', $definition->isAutowired() ? (Definition::AUTOWIRE_BY_TYPE === $definition->getAutowiredBy() ? 'by-type' : 'by-id') : 'no');
299299

300300
if ($autowiringTypes = $definition->getAutowiringTypes(false)) {
301301
$tableRows[] = array('Autowiring Types', implode(', ', $autowiringTypes));

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ private function getContainerDefinitionDocument(Definition $definition, $id = nu
371371
$serviceXML->setAttribute('lazy', $definition->isLazy() ? 'true' : 'false');
372372
$serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false');
373373
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
374-
$serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false');
374+
$serviceXML->setAttribute('autowired', $definition->isAutowired() ? (Definition::AUTOWIRE_BY_TYPE === $definition->getAutowiredBy() ? 'by-type' : 'by-id') : 'false');
375375
$serviceXML->setAttribute('file', $definition->getFile());
376376

377377
$calls = $definition->getMethodCalls();

‎src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+15-9Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
use Symfony\Component\DependencyInjection\TypedReference;
2121

2222
/**
23-
* Guesses constructor arguments of services definitions and try to instantiate services if necessary.
23+
* Inspects existing service definitions and wires the autowired ones using the type hints of their classes.
2424
*
2525
* @author Kévin Dunglas <dunglas@gmail.com>
26+
* @author Nicolas Grekas <p@tchwork.com>
2627
*/
2728
class AutowirePass extends AbstractRecursivePass
2829
{
@@ -345,12 +346,14 @@ private function getAutowiredReference($typeName, $autoRegister = true)
345346
return new Reference($typeName);
346347
}
347348

348-
if (null === $this->types) {
349-
$this->populateAvailableTypes();
350-
}
349+
if (Definition::AUTOWIRE_BY_TYPE === $this->currentDefinition->getAutowired()) {
350+
if (null === $this->types) {
351+
$this->populateAvailableTypes();
352+
}
351353

352-
if (isset($this->types[$typeName])) {
353-
return new Reference($this->types[$typeName]);
354+
if (isset($this->types[$typeName])) {
355+
return new Reference($this->types[$typeName]);
356+
}
354357
}
355358

356359
if ($autoRegister && $class = $this->container->getReflectionClass($typeName, true)) {
@@ -459,13 +462,16 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint)
459462
}
460463

461464
$currentId = $this->currentId;
462-
$this->currentId = $argumentId = sprintf('autowired.%s', $typeHint->name);
465+
$this->currentId = $argumentId = $typeHint->name;
463466

464467
$argumentDefinition = $this->container->register($argumentId, $typeHint->name);
465468
$argumentDefinition->setPublic(false);
466-
$argumentDefinition->setAutowired(true);
469+
$argumentDefinition->setAutowired($this->currentDefinition->getAutowired());
470+
$argumentDefinition->addTag('container.autoregistered');
467471

468-
$this->populateAvailableType($argumentId, $argumentDefinition);
472+
if (null !== $this->types) {
473+
$this->populateAvailableType($argumentId, $argumentDefinition);
474+
}
469475

470476
$this->processValue($argumentDefinition, true);
471477
$this->currentId = $currentId;

‎src/Symfony/Component/DependencyInjection/Definition.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Definition.php
+21-3Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
*/
2222
class Definition
2323
{
24+
const AUTOWIRE_BY_TYPE = 1;
25+
const AUTOWIRE_BY_ID = 2;
26+
2427
private $class;
2528
private $file;
2629
private $factory;
@@ -38,7 +41,7 @@ class Definition
3841
private $abstract = false;
3942
private $lazy = false;
4043
private $decoratedService;
41-
private $autowired = false;
44+
private $autowired = 0;
4245
private $autowiringTypes = array();
4346

4447
protected $arguments;
@@ -736,20 +739,35 @@ public function setAutowiringTypes(array $types)
736739
* @return bool
737740
*/
738741
public function isAutowired()
742+
{
743+
return (bool) $this->autowired;
744+
}
745+
746+
/**
747+
* Gets the autowiring mode.
748+
*
749+
* @return int
750+
*/
751+
public function getAutowired()
739752
{
740753
return $this->autowired;
741754
}
742755

743756
/**
744757
* Sets autowired.
745758
*
746-
* @param bool $autowired
759+
* @param int $autowired
747760
*
748761
* @return $this
749762
*/
750763
public function setAutowired($autowired)
751764
{
752-
$this->autowired = (bool) $autowired;
765+
$autowired = (int) $autowired;
766+
767+
if ($autowired && self::AUTOWIRE_BY_TYPE !== $autowired && self::AUTOWIRE_BY_ID !== $autowired) {
768+
throw new InvalidArgumentException(sprintf('Invalid argument: Definition::AUTOWIRE_BY_TYPE (%d) or Definition::AUTOWIRE_BY_ID (%d) expected, %d given.', self::AUTOWIRE_BY_TYPE, self::AUTOWIRE_BY_ID, $autowired));
769+
}
770+
$this->autowired = $autowired;
753771

754772
return $this;
755773
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+19-2Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ private function getServiceDefaults(\DOMDocument $xml, $file)
172172
}
173173
}
174174
if ($defaultsNode->hasAttribute('autowire')) {
175-
$defaults['autowire'] = XmlUtils::phpize($defaultsNode->getAttribute('autowire'));
175+
$defaults['autowire'] = $this->getAutowired($defaultsNode->getAttribute('autowire'), $file);
176176
}
177177
if ($defaultsNode->hasAttribute('public')) {
178178
$defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public'));
@@ -238,7 +238,7 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
238238
}
239239

240240
if ($value = $service->getAttribute('autowire')) {
241-
$definition->setAutowired(XmlUtils::phpize($value));
241+
$definition->setAutowired($this->getAutowired($value, $file));
242242
} elseif (isset($defaults['autowire'])) {
243243
$definition->setAutowired($defaults['autowire']);
244244
}
@@ -666,6 +666,23 @@ private function loadFromExtensions(\DOMDocument $xml)
666666
}
667667
}
668668

669+
private function getAutowired($value, $file)
670+
{
671+
if (is_bool($value = XmlUtils::phpize($value))) {
672+
return $value;
673+
}
674+
675+
if ('by-type' === $value) {
676+
return Definition::AUTOWIRE_BY_TYPE;
677+
}
678+
679+
if ('by-id' === $value) {
680+
return Definition::AUTOWIRE_BY_ID;
681+
}
682+
683+
throw new InvalidArgumentException(sprintf('Invalid autowire attribute: "by-type", "by-id", "true" or "false" expected, "%s" given in "%s".', $value, $file));
684+
}
685+
669686
/**
670687
* Converts a \DomElement object to a PHP array.
671688
*

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,14 @@ private function parseDefinition($id, $service, $file, array $defaults)
500500

501501
$autowire = isset($service['autowire']) ? $service['autowire'] : (isset($defaults['autowire']) ? $defaults['autowire'] : null);
502502
if (null !== $autowire) {
503+
if ('by_type' === $autowire) {
504+
$autowire = Definition::AUTOWIRE_BY_TYPE;
505+
} elseif ('by_id' === $autowire) {
506+
$autowire = Definition::AUTOWIRE_BY_ID;
507+
} elseif (!is_bool($autowire)) {
508+
throw new InvalidArgumentException(sprintf('Invalid autowire attribute: "by_type", "by_id", true or false expected, "%s" given in "%s".', is_string($autowire) ? $autowire : gettype($autowire), $file));
509+
}
510+
503511
$definition->setAutowired($autowire);
504512
}
505513

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+10-4Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
<xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
103103
</xsd:choice>
104104
<xsd:attribute name="public" type="boolean" />
105-
<xsd:attribute name="autowire" type="boolean" />
105+
<xsd:attribute name="autowire" type="autowire" />
106106
<xsd:attribute name="inherit-tags" type="boolean" />
107107
</xsd:complexType>
108108

@@ -131,7 +131,7 @@
131131
<xsd:attribute name="decorates" type="xsd:string" />
132132
<xsd:attribute name="decoration-inner-name" type="xsd:string" />
133133
<xsd:attribute name="decoration-priority" type="xsd:integer" />
134-
<xsd:attribute name="autowire" type="boolean" />
134+
<xsd:attribute name="autowire" type="autowire" />
135135
<xsd:attribute name="inherit-tags" type="boolean" />
136136
</xsd:complexType>
137137

@@ -151,7 +151,7 @@
151151
<xsd:attribute name="public" type="boolean" />
152152
<xsd:attribute name="lazy" type="boolean" />
153153
<xsd:attribute name="abstract" type="boolean" />
154-
<xsd:attribute name="autowire" type="boolean" />
154+
<xsd:attribute name="autowire" type="autowire" />
155155
</xsd:complexType>
156156

157157
<xsd:complexType name="prototype">
@@ -172,7 +172,7 @@
172172
<xsd:attribute name="lazy" type="boolean" />
173173
<xsd:attribute name="abstract" type="boolean" />
174174
<xsd:attribute name="parent" type="xsd:string" />
175-
<xsd:attribute name="autowire" type="boolean" />
175+
<xsd:attribute name="autowire" type="autowire" />
176176
<xsd:attribute name="inherit-tags" type="boolean" />
177177
</xsd:complexType>
178178

@@ -279,4 +279,10 @@
279279
<xsd:pattern value="(%.+%|true|false)" />
280280
</xsd:restriction>
281281
</xsd:simpleType>
282+
283+
<xsd:simpleType name="autowire">
284+
<xsd:restriction base="xsd:string">
285+
<xsd:pattern value="(true|false|by-type|by-id)" />
286+
</xsd:restriction>
287+
</xsd:simpleType>
282288
</xsd:schema>

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,15 @@ public function testCreateDefinition()
235235
$pass->process($container);
236236

237237
$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
238-
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
238+
$this->assertEquals(Dunglas::class, $container->getDefinition('coop_tilleuls')->getArgument(0));
239239

240-
$dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
240+
$dunglasDefinition = $container->getDefinition(Dunglas::class);
241241
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
242242
$this->assertFalse($dunglasDefinition->isPublic());
243243
$this->assertCount(1, $dunglasDefinition->getArguments());
244-
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille', $dunglasDefinition->getArgument(0));
244+
$this->assertEquals(Lille::class, $dunglasDefinition->getArgument(0));
245245

246-
$lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
246+
$lilleDefinition = $container->getDefinition(Lille::class);
247247
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
248248
}
249249

@@ -532,7 +532,7 @@ public function testTypedReference()
532532
$pass = new AutowirePass();
533533
$pass->process($container);
534534

535-
$this->assertSame(A::class, $container->getDefinition('autowired.'.A::class)->getClass());
535+
$this->assertSame(A::class, $container->getDefinition(A::class)->getClass());
536536
}
537537

538538
/**
@@ -555,8 +555,8 @@ public function testGetterOverriding()
555555
$overridenGetters = $container->getDefinition('getter_overriding')->getOverriddenGetters();
556556
$this->assertEquals(array(
557557
'getexplicitlydefined' => new Reference('b'),
558-
'getfoo' => new Reference('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Foo'),
559-
'getbar' => new Reference('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Bar'),
558+
'getfoo' => new Reference(Foo::class),
559+
'getbar' => new Reference(Bar::class),
560560
), $overridenGetters);
561561
}
562562

@@ -666,7 +666,7 @@ public function testEmptyStringIsKept()
666666
* @dataProvider provideAutodiscoveredAutowiringOrder
667667
*
668668
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
669-
* @expectedExceptionMEssage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (autowired.Symfony\Component\DependencyInjection\Tests\Compiler\CollisionA, autowired.Symfony\Component\DependencyInjection\Tests\Compiler\CollisionB).
669+
* @expectedExceptionMEssage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (Symfony\Component\DependencyInjection\Tests\Compiler\CollisionA, Symfony\Component\DependencyInjection\Tests\Compiler\CollisionB).
670670
*/
671671
public function testAutodiscoveredAutowiringOrder($class)
672672
{

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.