Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4a5f22b

Browse files
feature #22256 [DI] Reduce complexity of autowiring (nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DI] Reduce complexity of autowiring | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no (tweaking existing ones) | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - - optional args are autowired - methods with only optional args are autowired - default values of required args when possible Both first changes remove the behavior delta between constructors and setters, and is expected to me now that things are more explicit. This reduces the "know-how" requirements for using autowiring and is easier to get correct intuitively. The 3rd change plays nice with named args. Commits ------- 146f074 [DI] Reduce complexity of autowiring
2 parents 22bb403 + 146f074 commit 4a5f22b

File tree

2 files changed

+11
-20
lines changed

2 files changed

+11
-20
lines changed

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,8 @@ private function autowireCalls(\ReflectionClass $reflectionClass, array $methodC
230230
*/
231231
private function autowireMethod(\ReflectionMethod $reflectionMethod, array $arguments)
232232
{
233-
$isConstructor = $reflectionMethod->isConstructor();
234233
$class = $reflectionMethod->class;
235234
$method = $reflectionMethod->name;
236-
237-
if (!$isConstructor && !$arguments && !$reflectionMethod->getNumberOfRequiredParameters()) {
238-
throw new RuntimeException(sprintf('Cannot autowire service "%s": method %s() has only optional arguments, thus must be wired explicitly.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
239-
}
240235
$parameters = $reflectionMethod->getParameters();
241236
if (method_exists('ReflectionMethod', 'isVariadic') && $reflectionMethod->isVariadic()) {
242237
array_pop($parameters);
@@ -246,9 +241,6 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
246241
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
247242
continue;
248243
}
249-
if (!$isConstructor && $parameter->isOptional() && !array_key_exists($index, $arguments)) {
250-
break;
251-
}
252244

253245
$type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true);
254246

@@ -258,7 +250,7 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
258250
}
259251

260252
// no default value? Then fail
261-
if (!$parameter->isOptional()) {
253+
if (!$parameter->isDefaultValueAvailable()) {
262254
throw new RuntimeException(sprintf('Cannot autowire service "%s": argument $%s of method %s() must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));
263255
}
264256

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

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -386,21 +386,19 @@ public function testScalarArgsCannotBeAutowired()
386386
$container->getDefinition('arg_no_type_hint');
387387
}
388388

389-
/**
390-
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
391-
* @expectedExceptionMessage Cannot autowire service "not_really_optional_scalar": argument $foo of method Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArgumentsOptionalScalarNotReallyOptional::__construct() must have a type-hint or be given a value explicitly.
392-
*/
393-
public function testOptionalScalarNotReallyOptionalThrowException()
389+
public function testOptionalScalarNotReallyOptionalUsesDefaultValue()
394390
{
395391
$container = new ContainerBuilder();
396392

397393
$container->register('a', __NAMESPACE__.'\A');
398394
$container->register('lille', __NAMESPACE__.'\Lille');
399-
$container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional')
395+
$definition = $container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional')
400396
->setAutowired(true);
401397

402398
$pass = new AutowirePass();
403399
$pass->process($container);
400+
401+
$this->assertSame('default_val', $definition->getArgument(1));
404402
}
405403

406404
public function testOptionalScalarArgsDontMessUpOrder()
@@ -637,7 +635,12 @@ public function testNotWireableCalls($method, $expectedMsg)
637635
{
638636
$container = new ContainerBuilder();
639637

640-
$foo = $container->register('foo', NotWireable::class)->setAutowired(true);
638+
$foo = $container->register('foo', NotWireable::class)->setAutowired(true)
639+
->addMethodCall('setBar', array())
640+
->addMethodCall('setOptionalNotAutowireable', array())
641+
->addMethodCall('setOptionalNoTypeHint', array())
642+
->addMethodCall('setOptionalArgNoAutowireable', array())
643+
;
641644

642645
if ($method) {
643646
$foo->addMethodCall($method, array());
@@ -659,10 +662,6 @@ public function provideNotWireableCalls()
659662
{
660663
return array(
661664
array('setNotAutowireable', 'Cannot autowire service "foo": argument $n of method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setNotAutowireable() has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass" but this class does not exist.'),
662-
array('setBar', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setBar() has only optional arguments, thus must be wired explicitly.'),
663-
array('setOptionalNotAutowireable', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalNotAutowireable() has only optional arguments, thus must be wired explicitly.'),
664-
array('setOptionalNoTypeHint', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalNoTypeHint() has only optional arguments, thus must be wired explicitly.'),
665-
array('setOptionalArgNoAutowireable', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalArgNoAutowireable() has only optional arguments, thus must be wired explicitly.'),
666665
array(null, 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setProtectedMethod() must be public.'),
667666
);
668667
}

0 commit comments

Comments
 (0)