-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Autowiring] Add interface FQCN as a valid service name to avoid collisions #21132
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
Sounds hard to support without having a dedicated system in services:
CollisionInterface: '@app.b'
app.a:
class: A
autowire: true
app.b:
class: A
app.use_collision:
class: UseCollision
autowire: true |
Shouldn't we deprecate the |
@@ -338,11 +338,15 @@ private function set($type, $id) | |||
*/ | |||
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) | |||
{ | |||
if (isset($this->ambiguousServiceTypes[$typeHint->name])) { | |||
if (isset($this->ambiguousServiceTypes[$typeHintName = $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.
Why is necessary to create the $typeHintName
variable? It makes the code harder to read for no benefit over using the prop directly.
{ | ||
$container = new ContainerBuilder(); | ||
|
||
$container->register('c1', __NAMESPACE__.'\CollisionA'); |
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.
You can use CollisionA::class
for Symfony 3+. Same of lines below.
I'm for it, but should it be done here or another PR? Also should this be merged in master or an older branch? |
@GuilhemN I'm not sure to understand your concern, all services are registered being process that way so the order does not matter. |
@theofidry oops, I didn't realize it was a PR and I was thinking you'll try to implement it otherwise... 😐 LGTM 👍 I'm also for deprecating the |
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; | ||
$matchingServices = implode(', ', $this->ambiguousServiceTypes[$typeHint->name]); | ||
|
||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices), 1); | ||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices)); |
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.
needs to be reverted
@dunglas updated, but I'm still unsure on which branch we should merge this as if we want to deprecate |
the deprecation part is for master for sure |
@nicolas-grekas I'm actually not sure if this should be considered a feature or a bug (hence my question of which branch to target). The PR doesn't need to be split, deprecating |
👍 |
@@ -339,6 +339,10 @@ private function set($type, $id) | |||
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) | |||
{ | |||
if (isset($this->ambiguousServiceTypes[$typeHint->name])) { | |||
if ($this->container->has($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 this be moved here to avoid building the map when not necessary?
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.
Good point, gonna try
Closing, see ##21494. |
Thanks :) |
As of now, if you have:
It would fail, because you have
app.a
andapp.b
which are both implementingCollisionInterface
. However as you can see, in this scenario this is a bit stupid, as if you bother doingCollisionInterface: '@app.b'
, this is equivalent to (or rather should be IMO) have:You might wonder what's the diff and why bother yourself with that, the diff IMO is the location of your service definitions. For example I may try to follow a more DDD oriented architecture, e.g. the hexagonal architecture, where I have:
and try to have something like:
I am not sure if this can be caused any BC and if this should be considered as a feature or a bugfix.
/cc @dunglas