-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[FrameworkBundle] Multiple services on one Command class #19305
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
This way, a Command class can be used in more than just one service without breaking registerCommands of HttpKernel component.
This way, a Command class can be used in more than just one service without breaking registerCommands of HttpKernel component.
…issue_19001 Conflicts: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConsoleCommandPass.php src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConsoleCommandPassTest.php
$container->addCompilerPass(new AddConsoleCommandPass()); | ||
$container->setParameter('my-command.class', 'Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\MyCommand'); | ||
|
||
$definition1 = new Definition('%my-command.class%'); |
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.
Just put this in a variable, no need to use parameters to define class names
So now that you can register the same command service twice, how will you solve the conflicting name problem? |
@iltar: I guess it's up to you to configure a different name according to a constructor argument or whatever. |
This feature is closely related to another; Lazy command initialization. Ideally I'd configure the name via the tag. |
No, but it's come up quite a few times. The current system lets Commands define their own name, which works. However, this means the command has to be initialized. So if you have 20 commands, every single command has to be instantiated in order to get the name. The problem arises when you start using command as a service (my preference). It means that every single command will be initialized with all their dependencies. Hence there should be some kind of support of defining and retrieving their names without initializing them. |
Now that I think of it, Commands could be decorated. In a compiler pass you could do something that would eventually trigger this:
|
@@ -37,7 +37,11 @@ public function process(ContainerBuilder $container) | |||
if (!is_subclass_of($class, 'Symfony\\Component\\Console\\Command\\Command')) { | |||
throw new \InvalidArgumentException(sprintf('The service "%s" tagged "console.command" must be a subclass of "Symfony\\Component\\Console\\Command\\Command".', $id)); | |||
} | |||
$container->setAlias($serviceId = 'console.command.'.strtolower(str_replace('\\', '_', $class)), $id); | |||
$serviceId = 'console.command.'.strtolower(str_replace('\\', '_', $class)); | |||
if ($container->hasAlias($serviceId)) { |
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.
Should be replaced by something like this to work for any number of commands.
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 prefer to enumerate the alias for services of the same command class? What do we gain by adding another loop into the foreach and using numbers?
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 actual proposition doesn't fix the current limitation but only reduce its impact.
For example still won't be able to have 3 commands with the same class.
If it is decided to fix this limitation it should be fully fixed.
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 uses the service name in the alias. For working services, the $id
has to be unique, which is given in the alias too.
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.
Oh indeed sorry i thought it was a number... looks good to me then.
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 little section can also be rearraged so that the check for $definition->isPublic()
comes first, and avoid making $serviceId
Also, the check for existing alias could be avoided by always making Seem that would break the automatic registration of Commands$serviceId
with ..._$id
- there is no harm in doing this
It would be nice if Symfony would handle its commands like any other class in a service. |
Are there any work arounds for the moment? I guess I just need to create subclasses for each service. |
Also, I would call this a bug fix not a feature. |
@mcfedr Subclasses are my current workaround. I marked the PR as feature because commands as a service were introduced in Symfony 2.4 and we're looking on legacy-code from the time before that. It just didn't grow with the rest. |
Ping. |
👍 Can you rebase to fix conflicts and get rid of the merge commit? Thanks. |
I've done the work in #22120 |
Based on my opened issue #19001, I created this PR to introduce the possibility of using multiple command-services with one command class. This should make Commands much more equal to other services in Symfony.