[DependencyInjection] Deprecate autowiring service auto-registration

This commit is contained in:
Guilhem Niot 2017-07-29 15:29:10 +02:00 committed by Nicolas Grekas
parent 531b294b21
commit 969a20780e
7 changed files with 130 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();
}
}