diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md index 503e74922c..7530e8aca0 100644 --- a/UPGRADE-3.4.md +++ b/UPGRADE-3.4.md @@ -4,6 +4,50 @@ UPGRADE FROM 3.3 to 3.4 DependencyInjection ------------------- + * Autowiring service auto-registration is deprecated and won't be supported + in Symfony 4.0. Explicitly inject your dependencies or create services + whose ids are their fully-qualified class name. + + Before: + + ```php + namespace App\Controller; + + use App\Mailer; + + class DefaultController + { + public function __construct(Mailer $mailer) { + // ... + } + + // ... + } + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + ``` + + After: + + ```php + // same PHP code + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + + # or + # App\Controller\DefaultController: + # arguments: { $mailer: "@App\Mailer" } + + App\Mailer: + autowire: true +  ``` + * Top-level anonymous services in XML are deprecated and will throw an exception in Symfony 4.0. Debug @@ -30,13 +74,13 @@ FrameworkBundle require symfony/stopwatch` in your `dev` environment. * Using the `KERNEL_DIR` environment variable or the automatic guessing based - on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4. + on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4. Set the `KERNEL_CLASS` environment variable to the fully-qualified class name - of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable - will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()` + of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable + will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()` or `KernelTestCase::getKernelClass()` method. - - * The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` + + * The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` methods are deprecated since 3.4 and will be removed in 4.0. * The `--no-prefix` option of the `translation:update` command is deprecated and @@ -83,7 +127,7 @@ TwigBridge * deprecated the `Symfony\Bridge\Twig\Form\TwigRenderer` class, use the `FormRenderer` class from the Form component instead - * deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability + * deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability to pass a command name as first argument * deprecated `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability @@ -95,7 +139,7 @@ TwigBundle * deprecated the `Symfony\Bundle\TwigBundle\Command\DebugCommand` class, use the `DebugCommand` class from the Twig bridge instead - * deprecated relying on the `ContainerAwareInterface` implementation for + * deprecated relying on the `ContainerAwareInterface` implementation for `Symfony\Bundle\TwigBundle\Command\LintCommand` Validator diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 5a8042835c..65f0619525 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -77,6 +77,50 @@ Debug DependencyInjection ------------------- + * Autowiring service auto-registration is not supported anymore. + Explicitly inject your dependencies or create services whose ids are + their fully-qualified class name. + + Before: + + ```php + namespace App\Controller; + + use App\Mailer; + + class DefaultController + { + public function __construct(Mailer $mailer) { + // ... + } + + // ... + } + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + ``` + + After: + + ```php + // same PHP code + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + + # or + # App\Controller\DefaultController: + # arguments: { $mailer: "@App\Mailer" } + + App\Mailer: + autowire: true +  ``` + * 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. * `_defaults` and `_instanceof` are now reserved service names in Yaml configurations. Please rename any services with that names. @@ -338,9 +382,9 @@ FrameworkBundle class instead. * Using the `KERNEL_DIR` environment variable and the automatic guessing based - on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()` + on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()` method implementation. Set the `KERNEL_CLASS` environment variable to the - fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()` + fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()` or `KernelTestCase::getKernelClass()` method instead. * The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory` class has been removed. @@ -349,10 +393,10 @@ FrameworkBundle * The `--no-prefix` option of the `translation:update` command has been removed. - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass` class has been removed. + * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass` class has been removed. Use the `Symfony\Component\HttpKernel\DependencyInjection\AddCacheClearerPass` class instead. - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass` class has been removed. + * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass` class has been removed. Use the `Symfony\Component\HttpKernel\DependencyInjection\AddCacheWarmerPass` class instead. * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass` @@ -554,7 +598,7 @@ TwigBridge * The `TwigRendererEngine::setEnvironment()` method has been removed. Pass the Twig Environment as second argument of the constructor instead. - * Removed `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability + * Removed `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability to pass a command name as first argument. * Removed `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index 3037dad65c..1ae4818cd4 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 3.4.0 ----- + * deprecated autowiring service auto-registration * deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method * deprecated support for top-level anonymous services in XML diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index a59444fcac..4e93e92aa6 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -477,6 +477,8 @@ class AutowirePass extends AbstractRecursivePass $this->currentId = $currentId; } + @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); + $this->container->log($this, sprintf('Type "%s" has been auto-registered for service "%s".', $type, $this->currentId)); return new TypedReference($argumentId, $type); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 757db3f229..adf83b1dbb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -287,6 +287,11 @@ class AutowirePassTest extends TestCase $this->assertEquals(CollisionInterface::class, (string) $container->getDefinition('a')->getArgument(0)); } + /** + * @group legacy + * @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. + * @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. + */ public function testCreateDefinition() { $container = new ContainerBuilder(); @@ -368,6 +373,8 @@ class AutowirePassTest extends TestCase $aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument'); $aDefinition->setAutowired(true); + $container->register(Dunglas::class, Dunglas::class); + $pass = new AutowirePass(); $pass->process($container); } @@ -383,6 +390,8 @@ class AutowirePassTest extends TestCase $aDefinition = $container->register('a', __NAMESPACE__.'\BadParentTypeHintedArgument'); $aDefinition->setAutowired(true); + $container->register(Dunglas::class, Dunglas::class); + $pass = new AutowirePass(); $pass->process($container); } @@ -595,6 +604,10 @@ class AutowirePassTest extends TestCase ); } + /** + * @group legacy + * @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. + */ public function testTypedReference() { $container = new ContainerBuilder(); @@ -653,6 +666,8 @@ class AutowirePassTest extends TestCase $barDefinition = $container->register('bar', __NAMESPACE__.'\Bar'); $barDefinition->setAutowired(true); + $container->register(Foo::class, Foo::class); + $pass = new AutowirePass(); $pass->process($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 6e7889725e..4afb445c68 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -28,6 +28,7 @@ use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber; use Symfony\Component\DependencyInjection\Variable; use Symfony\Component\ExpressionLanguage\Expression; @@ -560,6 +561,9 @@ class PhpDumperTest extends TestCase )) ; $container->register(TestServiceSubscriber::class, TestServiceSubscriber::class); + + $container->register(CustomDefinition::class, CustomDefinition::class) + ->setPublic(false); $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php index 01c385358b..4e45a4fe64 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php @@ -28,16 +28,16 @@ class ProjectServiceContainer extends Container { $this->services = array(); $this->normalizedIds = array( - 'autowired.symfony\\component\\dependencyinjection\\tests\\fixtures\\customdefinition' => 'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\customdefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'symfony\\component\\dependencyinjection\\tests\\fixtures\\testservicesubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', ); $this->methodMap = array( + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getSymfony_Component_DependencyInjection_Tests_Fixtures_TestServiceSubscriberService', - 'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService', 'foo_service' => 'getFooServiceService', ); $this->privates = array( - 'autowired.Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, ); $this->aliases = array(); @@ -87,23 +87,23 @@ class ProjectServiceContainer extends Container protected function getFooServiceService() { 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 () { - $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 ?: '_'}); + $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 ?: '_'}); }, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () { $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 ?: '_'}); }, 'bar' => function () { $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 ?: '_'}); }, 'baz' => function () { - $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 ?: '_'}); + $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 ?: '_'}); }))); } /** - * Gets the private 'autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared autowired service. + * Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service. * * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition */ - protected function getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService() + protected function getSymfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService() { - return $this->services['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); + return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); } }