Skip to content

Commit 969a207

Browse files
GuilhemNnicolas-grekas
authored andcommitted
[DependencyInjection] Deprecate autowiring service auto-registration
1 parent 531b294 commit 969a207

File tree

7 files changed

+130
-20
lines changed

7 files changed

+130
-20
lines changed

UPGRADE-3.4.md

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,50 @@ UPGRADE FROM 3.3 to 3.4
44
DependencyInjection
55
-------------------
66

7+
* Autowiring service auto-registration is deprecated and won't be supported
8+
in Symfony 4.0. Explicitly inject your dependencies or create services
9+
whose ids are their fully-qualified class name.
10+
11+
Before:
12+
13+
```php
14+
namespace App\Controller;
15+
16+
use App\Mailer;
17+
18+
class DefaultController
19+
{
20+
public function __construct(Mailer $mailer) {
21+
// ...
22+
}
23+
24+
// ...
25+
}
26+
```
27+
```yml
28+
services:
29+
App\Controller\DefaultController:
30+
autowire: true
31+
```
32+
33+
After:
34+
35+
```php
36+
// same PHP code
37+
```
38+
```yml
39+
services:
40+
App\Controller\DefaultController:
41+
autowire: true
42+
43+
# or
44+
# App\Controller\DefaultController:
45+
# arguments: { $mailer: "@App\Mailer" }
46+
47+
App\Mailer:
48+
autowire: true
49+
 ```
50+
751
* Top-level anonymous services in XML are deprecated and will throw an exception in Symfony 4.0.
852

953
Debug
@@ -30,13 +74,13 @@ FrameworkBundle
3074
require symfony/stopwatch` in your `dev` environment.
3175

3276
* Using the `KERNEL_DIR` environment variable or the automatic guessing based
33-
on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4.
77+
on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4.
3478
Set the `KERNEL_CLASS` environment variable to the fully-qualified class name
35-
of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable
36-
will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()`
79+
of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable
80+
will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()`
3781
or `KernelTestCase::getKernelClass()` method.
38-
39-
* The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()`
82+
83+
* The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()`
4084
methods are deprecated since 3.4 and will be removed in 4.0.
4185

4286
* The `--no-prefix` option of the `translation:update` command is deprecated and
@@ -83,7 +127,7 @@ TwigBridge
83127
* deprecated the `Symfony\Bridge\Twig\Form\TwigRenderer` class, use the `FormRenderer`
84128
class from the Form component instead
85129

86-
* deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
130+
* deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
87131
to pass a command name as first argument
88132

89133
* deprecated `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability
@@ -95,7 +139,7 @@ TwigBundle
95139
* deprecated the `Symfony\Bundle\TwigBundle\Command\DebugCommand` class, use the `DebugCommand`
96140
class from the Twig bridge instead
97141

98-
* deprecated relying on the `ContainerAwareInterface` implementation for
142+
* deprecated relying on the `ContainerAwareInterface` implementation for
99143
`Symfony\Bundle\TwigBundle\Command\LintCommand`
100144

101145
Validator

UPGRADE-4.0.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,50 @@ Debug
7777
DependencyInjection
7878
-------------------
7979

80+
* Autowiring service auto-registration is not supported anymore.
81+
Explicitly inject your dependencies or create services whose ids are
82+
their fully-qualified class name.
83+
84+
Before:
85+
86+
```php
87+
namespace App\Controller;
88+
89+
use App\Mailer;
90+
91+
class DefaultController
92+
{
93+
public function __construct(Mailer $mailer) {
94+
// ...
95+
}
96+
97+
// ...
98+
}
99+
```
100+
```yml
101+
services:
102+
App\Controller\DefaultController:
103+
autowire: true
104+
```
105+
106+
After:
107+
108+
```php
109+
// same PHP code
110+
```
111+
```yml
112+
services:
113+
App\Controller\DefaultController:
114+
autowire: true
115+
116+
# or
117+
# App\Controller\DefaultController:
118+
# arguments: { $mailer: "@App\Mailer" }
119+
120+
App\Mailer:
121+
autowire: true
122+
 ```
123+
80124
* Autowiring services based on the types they implement is not supported anymore. Rename (or alias) your services to their FQCN id to make them autowirable.
81125

82126
* `_defaults` and `_instanceof` are now reserved service names in Yaml configurations. Please rename any services with that names.
@@ -338,9 +382,9 @@ FrameworkBundle
338382
class instead.
339383

340384
* Using the `KERNEL_DIR` environment variable and the automatic guessing based
341-
on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()`
385+
on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()`
342386
method implementation. Set the `KERNEL_CLASS` environment variable to the
343-
fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()`
387+
fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()`
344388
or `KernelTestCase::getKernelClass()` method instead.
345389

346390
* The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory` class has been removed.
@@ -349,10 +393,10 @@ FrameworkBundle
349393
* The `--no-prefix` option of the `translation:update` command has
350394
been removed.
351395

352-
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass` class has been removed.
396+
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass` class has been removed.
353397
Use the `Symfony\Component\HttpKernel\DependencyInjection\AddCacheClearerPass` class instead.
354398

355-
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass` class has been removed.
399+
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass` class has been removed.
356400
Use the `Symfony\Component\HttpKernel\DependencyInjection\AddCacheWarmerPass` class instead.
357401

358402
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass`
@@ -554,7 +598,7 @@ TwigBridge
554598
* The `TwigRendererEngine::setEnvironment()` method has been removed.
555599
Pass the Twig Environment as second argument of the constructor instead.
556600

557-
* Removed `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
601+
* Removed `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
558602
to pass a command name as first argument.
559603

560604
* Removed `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
3.4.0
55
-----
66

7+
* deprecated autowiring service auto-registration
78
* deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method
89
* deprecated support for top-level anonymous services in XML
910

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ private function createAutowiredDefinition($type)
477477
$this->currentId = $currentId;
478478
}
479479

480+
@trigger_error(sprintf('Using autowiring service auto-registration for type "%s" is deprecated since version 3.4 and won\'t be supported in 4.0. Create a service named "%s" instead.', $type, $type), E_USER_DEPRECATED);
481+
480482
$this->container->log($this, sprintf('Type "%s" has been auto-registered for service "%s".', $type, $this->currentId));
481483

482484
return new TypedReference($argumentId, $type);

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ public function testWithTypeSet()
287287
$this->assertEquals(CollisionInterface::class, (string) $container->getDefinition('a')->getArgument(0));
288288
}
289289

290+
/**
291+
* @group legacy
292+
* @expectedDeprecation Using autowiring service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\Lille" is deprecated since version 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\Lille" instead.
293+
* @expectedDeprecation Using autowiring service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas" is deprecated since version 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas" instead.
294+
*/
290295
public function testCreateDefinition()
291296
{
292297
$container = new ContainerBuilder();
@@ -368,6 +373,8 @@ public function testClassNotFoundThrowsException()
368373
$aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument');
369374
$aDefinition->setAutowired(true);
370375

376+
$container->register(Dunglas::class, Dunglas::class);
377+
371378
$pass = new AutowirePass();
372379
$pass->process($container);
373380
}
@@ -383,6 +390,8 @@ public function testParentClassNotFoundThrowsException()
383390
$aDefinition = $container->register('a', __NAMESPACE__.'\BadParentTypeHintedArgument');
384391
$aDefinition->setAutowired(true);
385392

393+
$container->register(Dunglas::class, Dunglas::class);
394+
386395
$pass = new AutowirePass();
387396
$pass->process($container);
388397
}
@@ -595,6 +604,10 @@ public function testExplicitMethodInjection()
595604
);
596605
}
597606

607+
/**
608+
* @group legacy
609+
* @expectedDeprecation Using autowiring service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\A" is deprecated since version 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\A" instead.
610+
*/
598611
public function testTypedReference()
599612
{
600613
$container = new ContainerBuilder();
@@ -653,6 +666,8 @@ public function testIgnoreServiceWithClassNotExisting()
653666
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
654667
$barDefinition->setAutowired(true);
655668

669+
$container->register(Foo::class, Foo::class);
670+
656671
$pass = new AutowirePass();
657672
$pass->process($container);
658673

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Symfony\Component\DependencyInjection\Definition;
2929
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
3030
use Symfony\Component\DependencyInjection\ServiceLocator;
31+
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
3132
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
3233
use Symfony\Component\DependencyInjection\Variable;
3334
use Symfony\Component\ExpressionLanguage\Expression;
@@ -560,6 +561,9 @@ public function testServiceSubscriber()
560561
))
561562
;
562563
$container->register(TestServiceSubscriber::class, TestServiceSubscriber::class);
564+
565+
$container->register(CustomDefinition::class, CustomDefinition::class)
566+
->setPublic(false);
563567
$container->compile();
564568

565569
$dumper = new PhpDumper($container);

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ public function __construct()
2828
{
2929
$this->services = array();
3030
$this->normalizedIds = array(
31-
'autowired.symfony\\component\\dependencyinjection\\tests\\fixtures\\customdefinition' => 'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
31+
'symfony\\component\\dependencyinjection\\tests\\fixtures\\customdefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
3232
'symfony\\component\\dependencyinjection\\tests\\fixtures\\testservicesubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber',
3333
);
3434
$this->methodMap = array(
35+
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService',
3536
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getSymfony_Component_DependencyInjection_Tests_Fixtures_TestServiceSubscriberService',
36-
'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService',
3737
'foo_service' => 'getFooServiceService',
3838
);
3939
$this->privates = array(
40-
'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,
40+
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,
4141
);
4242

4343
$this->aliases = array();
@@ -87,23 +87,23 @@ protected function getSymfony_Component_DependencyInjection_Tests_Fixtures_TestS
8787
protected function getFooServiceService()
8888
{
8989
return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () {
90-
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()) && false ?: '_'});
90+
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()) && false ?: '_'});
9191
}, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () {
9292
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->get('Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber')) && false ?: '_'});
9393
}, 'bar' => function () {
9494
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->get('Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber')) && false ?: '_'});
9595
}, 'baz' => function () {
96-
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()) && false ?: '_'});
96+
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()) && false ?: '_'});
9797
})));
9898
}
9999

100100
/**
101-
* Gets the private 'autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared autowired service.
101+
* Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service.
102102
*
103103
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition
104104
*/
105-
protected function getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()
105+
protected function getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()
106106
{
107-
return $this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition();
107+
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition();
108108
}
109109
}

0 commit comments

Comments
 (0)