-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DI] Don't use auto-registered services to populate type-candidates #22254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
if (isset($arguments[$index])) { | ||
continue; | ||
} | ||
|
||
// no default value? Then fail | ||
if (!$parameter->isOptional()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this check isDefaultValueAvailable
and allowsNull
instead ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a check for isDefaultValueAvailable
- but none for allowsNull
because unless I'm wrong, we don't need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and I just reverted this change, because there is nothing wrong here: at this stage, an optional arg must have a default value, (but an arg with a default value is not necessarily optional)
so all good to me as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current behavior is a tested one, so I'll adjust on master to fit named args, nothing to do here to me
|
@theofidry it is directly related: #22162 uses The concrete consequence of this PR is that instead of failing to autowire in some order-related situations, it will make it to always fail (#22170 tries to make it always work, but I'd prefer to get rid of the existing 💩 instead :).) |
@nicolas-grekas I prefer your approach rather than adding more complex magic requiring a 2-step processing of definitions. |
4a0d0bd
to
881b2e8
Compare
@@ -252,13 +262,11 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) | |||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface)); | |||
} | |||
|
|||
$argumentId = sprintf('autowired.%s', $typeHint->name); | |||
$this->autowired[$typeHint->name] = $argumentId = sprintf('autowired.%s', $typeHint->name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we populate just one type instead? e.g. $this->types[$typeHint->name] = $argumentId
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into this, and didn't find much benefit in doing so, counting LOC - also conceptually that's no exactly the same (as hinted by https://github.com/symfony/symfony/pull/22254/files#diff-62df969ae028c559d33ffd256de1ac49R135)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as there is the false
support I don't see much benefit too.
Fine for me as is then 👍
|
||
$arguments = $definition->getArguments(); | ||
foreach ($constructor->getParameters() as $index => $parameter) { | ||
foreach ($parameters as $index => $parameter) { | ||
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we actually need this, it makes one more thing to learn while we could achieve the same using manual indexes or named arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
named arguments are a 3.3 feature. This PR targets 2.8. So we need to keep this feature in 2.8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is committed behavior, we can't change now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, that's a comment for 3.3, I'll open a different PR to discuss this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This behavior is still useful in XML (but not in YAML IMO).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
881b2e8
to
992c677
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍, it should have been the default since the beginning. The only thing annoying to me is that this change may break a few apps. Maybe should this "new" behavior mentioned in the CHANGELOG?
Not sure where this should be added. It will be in the changelog as usual of course. |
Thank you @nicolas-grekas. |
…andidates (nicolas-grekas) This PR was merged into the 2.8 branch. Discussion ---------- [DI] Don't use auto-registered services to populate type-candidates | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no (every bug fix is a bc break, isn't it?) | Deprecations? | no | Tests pass? | yes | Fixed tickets | #22162, ~~#21658~~ | License | MIT | Doc PR | symfony/symfony-docs#... <!--highly recommended for new features--> Alternative to #22170 and ~~#21665~~. The core issue fixed here is that auto-registered services should *not* be used as type-candidates. The culprit is this line: `$this->populateAvailableType($argumentId, $argumentDefinition);` Doing so creates a series of wtf-issues (the linked ones), with no simple fixes (the linked PRs are just dealing with the simplest cases, but the real fix would require a reboot of autowiring for every newly discovered types.) The other changes accommodate for the removal of the population of the `types` property, and fix a few other issues found along the way: - variadic constructors - empty strings injection - tail args removal when they match the existing defaults Commits ------- 992c677 [DI] Don't use auto-registered services to populate type-candidates
Not entirely sure if it was caused by this change or some other commit but the fact is that in Symfony 3.2.7 autowiring doesn't work for me at all (3.2.6 is fine). In the compiled container many services are created with no arguments at all instead of their autowired dependencies.
|
Last comment fixed in #22311 |
#21658Alternative to #22170 and
#21665.The core issue fixed here is that auto-registered services should not be used as type-candidates.
The culprit is this line:
$this->populateAvailableType($argumentId, $argumentDefinition);
Doing so creates a series of wtf-issues (the linked ones), with no simple fixes (the linked PRs are just dealing with the simplest cases, but the real fix would require a reboot of autowiring for every newly discovered types.)
The other changes accommodate for the removal of the population of the
types
property, and fix a few other issues found along the way: