-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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).