Skip to content

Commit

Permalink
Fixed @wouterj's feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Loïc Chardonnet committed Mar 2, 2014
1 parent e137951 commit 6a7a25f
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 29 deletions.
53 changes: 24 additions & 29 deletions components/console/commands_as_services.rst
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
.. index::
single: Console; Commands as Services

How to define Commands as Services
How to Define Commands as Services
==================================

.. versionadded:: 2.4
Support for registering commands in the service container was added in
Support for registering commands in the service container was introduced in
version 2.4.

By default, Symfony will take a look in the ``Command`` directory of your
bundles and automatically register your commands. For the ones implementing
the ``ContainerAwareCommand`` interface, Symfony will even inject the container.

While making life easier, this default implementation has some drawbacks in some
situations:

* what if you want your command to be defined elsewhere than in the ``Command``
folder?
* what if you want to register conditionally your command, depending on the
* What if you want your command to be defined elsewhere than in the ``Command``
directory?
* what if you want to conditionally register your command, depending on the
current environment or on the availability of some dependencies?
* what if you need to access dependencies before the ``setContainer`` is called
(for example in the ``configure`` method)?
* what if you need to access dependencies before the ``setContainer()`` is
called (for example in the ``configure()`` method)?
* what if you want to reuse a command many times, but with different
dependencies or parameters?

Expand All @@ -46,45 +45,41 @@ defining it with the ``console.command`` tag:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<service id="acme_hello.command.my_command"
class="Acme\HelloBundle\Command\MyCommand">
<tag name="console.command" />
</service>
<services>
<service id="acme_hello.command.my_command"
class="Acme\HelloBundle\Command\MyCommand">
<tag name="console.command" />
</service>
</services>
</container>
.. code-block:: php
// app/config/config.php
$container
->register('acme_hello.command.my_command', 'Acme\HelloBundle\Command\MyCommand')
->addTag('console.command')
;
Here are some use cases.

Use dependencies and parameters in configure
--------------------------------------------
Use Case: Using Dependencies and Parameters to Set Default Values for Options
-----------------------------------------------------------------------------

For example, imagine you want to provide a default value for the ``name``
argument. You could:
Imagine you want to provide a default value for the ``name``option. You could
pass one of the following as the 5th argument of ``addOption()``:

* hard code a string and pass it as the 4th argument of ``addArgument``;
* allow the user to set the default value in the configuration;
* retrieve the default value from a service (a repository for example).
* an hardcoded string;
* a value coming from the configuration (allows the user to change it easily);
* a value computed by a service (e.g. a repository).

With a ``ContainerAwareCommand`` you wouldn't be able to retrieve the
configuration parameter, because the ``configure`` method is called in the
command's constructor. The only solution is to inject them through its
constructor:
configuration parameter, because the ``configure()`` method is called in the
constructor. The only solution is to inject them through it::

<?php
// src/Acme/DemoBundle/Command/GreetCommand.php
namespace Acme\DemoBundle\Command;

use Acme\DemoBundle\Entity\NameRepository;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -105,13 +100,13 @@ constructor:
$this
->setName('demo:greet')
->setDescription('Greet someone')
->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?', $defaultName)
->addOption('name', '-n', InputOption::VALUE_REQUIRED, 'Who do you want to greet?', $defaultName)
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$name = $input->getOption('name');

$output->writeln($name);
}
Expand Down
1 change: 1 addition & 0 deletions components/console/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ Learn More!
* :doc:`/components/console/usage`
* :doc:`/components/console/single_command_tool`
* :doc:`/components/console/events`
* :doc:`/components/console/commands_as_services`

.. _Packagist: https://packagist.org/packages/symfony/console
.. _ANSICON: https://github.com/adoxa/ansicon/releases

0 comments on commit 6a7a25f

Please sign in to comment.