Skip to content

[DependencyInjection] Create an util class to determine services implementing a FQCN #20940

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

Closed
wants to merge 1 commit into from

Conversation

GuilhemN
Copy link
Contributor

@GuilhemN GuilhemN commented Dec 15, 2016

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #18300
License MIT
Doc PR

Reopening of #18300.

This PR creates a new util class: the ServiceTypeHelper. It extracts some of the AutowirePass logic usable like this (only during the container compilation):

$container = new ContainerBuilder();
$helper = new ServiceTypeHelper($container);

$helper->getOfType(Bar::class);

This could be useful in the DunglasActionBundle, to detect when a class is already registered in the container.

Edit: one new advantage of using autowireTypes: the types map is no longer built if they are sufficient!

$services = $this->typeHelper->getOfType($type);
if (1 === count($services)) {
return $services[0];
} elseif (1 < count($services)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just if here


try {
$name = (new \ReflectionClass($class))->name;
} catch (\ReflectionException $e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this works fine only if you have a fallback autoloader throwing a ReflectionException as a last resort to avoid the fatal error. As you extracted the logic, you need to handle this requirement in your new service

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed in the AutowirePass because it fetches parameters type hint but this helper doesn't use anything else than the class name, is it still needed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the class may extend a non-existent parent class (if the service relies on an optional dependency which is not installed)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, it's updated in 98481b9.

*/
final class ServiceTypeHelper
{
private static $classesName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classNames would be a better name

*
* @param Definition $definition
*
* @return string|false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use string|null (a nullable string type) instead of this mixed type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it but I'm not sure that's worth it (I used ?: to not change the isset to a array_key_exists).

@stof
Copy link
Member

stof commented Dec 15, 2016

Does it work fine when the compiler pass registers new autowired services ? The compiler pass currently updates it type map for them, but you removed lots of the logic.

@GuilhemN
Copy link
Contributor Author

@stof I forgot to update this, it is fixed in 98481b9, precisely here.

$name = false;
}

return self::$classNames[$class] = $name ?: null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will assign null, not false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I put brackets around it, use false or use array_key_exists?

@nicolas-grekas
Copy link
Member

Generally speaking, types should not be used for wiring things. We added some features recently to make it possible (ie #21530 ) but there is a big difference: there, the type is used on a very local scope only (the config file that uses it). Here, it opens the door to global type-related side effects.
👎

@GuilhemN
Copy link
Contributor Author

@nicolas-grekas this proposal was mostly intended for the DunglasActionBundle but now that you implemented psr4 and _instanceof in a more generic way I think we indeed don't need it anymore.
Thanks for this features btw!

@GuilhemN GuilhemN closed this Feb 14, 2017
@nicolas-grekas nicolas-grekas modified the milestone: 3.x Mar 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants