@@ -8,21 +8,22 @@ How to Define Commands as Services
88 Support for registering commands in the service container was introduced in
99 version 2.4.
1010
11- By default, Symfony will take a look in the ``Command `` directory of your
12- bundles and automatically register your commands. For the ones implementing
13- the ``ContainerAwareCommand `` interface, Symfony will even inject the container.
14- While making life easier, this default implementation has some drawbacks in some
15- situations:
16-
17- * Define the command elsewhere than in the ``Command `` directory;
18- * Conditionally register your command, depending on the current environment or
19- on the availability of some dependencies;
20- * Access dependencies before the ``setContainer() `` is called (for example in
21- the ``configure() `` method);
22- * Reuse a command many times, but with different dependencies or parameters
23-
24- To solve those problems, you can register your command as a service by simply
25- defining it with the ``console.command `` tag:
11+ By default, Symfony will take a look in the ``Command `` directory of each
12+ bundle and automatically register your commands. If a command extends the
13+ :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Command\\ ContainerAwareCommand `,
14+ Symfony will even inject the container.
15+ While making life easier, this has some limitations:
16+
17+ * Your command must live in the ``Command `` directory;
18+ * There's no way to conditionally register your service based on the environment
19+ or availability of some dependencies;
20+ * You can't access the container in the ``configure() `` method (because
21+ ``setContainer `` hasn't been called yet);
22+ * You can't use the same class to create many commands (i.e. each with
23+ different configuration).
24+
25+ To solve these problems, you can register your command as a service and tag it
26+ with ``console.command ``:
2627
2728..configuration-block ::
2829
@@ -62,16 +63,17 @@ defining it with the ``console.command`` tag:
6263 Using Dependencies and Parameters to Set Default Values for Options
6364-------------------------------------------------------------------
6465
65- Imagine you want to provide a default value for the ``name``option. You could
66+ Imagine you want to provide a default value for the ``name `` option. You could
6667pass one of the following as the 5th argument of ``addOption() ``:
6768
68- *an hardcoded string;
69- * avalue coming from the configuration (allows the user to change it easily );
69+ *a hardcoded string;
70+ * acontainer parameter (e.g. something from parameters.yml );
7071* a value computed by a service (e.g. a repository).
7172
72- With a ``ContainerAwareCommand `` you wouldn't be able to retrieve the
73- configuration parameter, because the ``configure() `` method is called in the
74- constructor. The only solution is to inject them::
73+ By extending ``ContainerAwareCommand ``, only the first is possible, because you
74+ can't access the container inside the ``configure() `` method. Instead, inject
75+ any parameter or service you need into the constructor. For example, suppose you
76+ have some ``NameRepository `` service that you'll use to get your default value::
7577
7678 // src/Acme/DemoBundle/Command/GreetCommand.php
7779 namespace Acme\DemoBundle\Command;
@@ -110,8 +112,11 @@ constructor. The only solution is to inject them::
110112 }
111113 }
112114
115+ Now, just update the arguments of your service configuration like normal to
116+ inject the ``NameRepository ``. Great, you now have a dynamic default value!
117+
113118..caution ::
114119
115- When running the console, every command is instantiated, which means every
116- `` configure() `` method is called. Be careful with database queries, as
117- they could impact performance .
120+ Be careful not to actually do any work in `` configure `` (e.g. make database
121+ queries), as your code will be run, even if you're using the console to
122+ execute a different command .