-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
| Q | A |
|---|---|
| Bug report? | No |
| Feature request? | No |
| BC Break report? | no |
| RFC? | No |
| Symfony version | 3.4.0 |
The current autowiring behavior is:
If there is not a service whose id exactly matches the type AND there are 0 services in the container that have the type, a new, private, autowired service is auto-registered in the container and used for that argument.
In #22295, @nicolas-grekas proposed removing this. But, we decided not to, because it meant that all services would need to be explicitly wired. But with the PSR-4 service loader, that's not true anymore.
We should deprecate this "auto-registration" functionality from AutowirePass (
symfony/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
Lines 422 to 461 in d7992dc
| /** | |
| * Registers a definition for the type if possible or throws an exception. | |
| * | |
| * @param string $type | |
| * | |
| * @return TypedReference|null A reference to the registered definition | |
| */ | |
| private function createAutowiredDefinition($type) | |
| { | |
| if (!($typeHint = $this->container->getReflectionClass($type)) || !$typeHint->isInstantiable()) { | |
| return; | |
| } | |
| $currentId = $this->currentId; | |
| $this->currentId = $type; | |
| $this->autowired[$type] = $argumentId = sprintf('autowired.%s', $type); | |
| $argumentDefinition = new Definition($type); | |
| $argumentDefinition->setPublic(false); | |
| $argumentDefinition->setAutowired(true); | |
| try { | |
| $originalThrowSetting = $this->throwOnAutowiringException; | |
| $this->throwOnAutowiringException = true; | |
| $this->processValue($argumentDefinition, true); | |
| $this->container->setDefinition($argumentId, $argumentDefinition); | |
| } catch (AutowiringFailedException $e) { | |
| $this->autowired[$type] = false; | |
| $this->lastFailure = $e->getMessage(); | |
| $this->container->log($this, $this->lastFailure); | |
| return; | |
| } finally { | |
| $this->throwOnAutowiringException = $originalThrowSetting; | |
| $this->currentId = $currentId; | |
| } | |
| $this->container->log($this, sprintf('Type "%s" has been auto-registered for service "%s".', $type, $this->currentId)); | |
| return new TypedReference($argumentId, $type); | |
| } |
This "auto-registration" in AutowirePass is problematic because we can't apply instanceof to those definitions... which is a bit unexpected. Removing it also simplifies the autowiring logic: there's one less case to explain. I chatted with @dunglas about this already (https://twitter.com/dunglas/status/881557361042894849).