0

By default Symfony tries to scan every bundle directory for a folder called 'Command' and searches for Console\Command classes in there.

But when you want to use the DIC and DI in you console commands there is another approach to make this happen. According to this article it should be possible to load your console commands with the dependency injection container, so I tried.

I made a service.xml:

<services>
    <service id="atlas_cli.helper.anonymize" class="AtlasCliBundle\Services\AnonymizerHelperService" public="false" />
    <service id="atlas_cli.helper.dbconfiguration" class="AtlasCliBundle\Services\ConfigurationHelperService" public="false" />
    <service id="atlas_cli.helper.schemadump" class="AtlasCliBundle\Services\SchemaDumpHelperService" public="false" />
    <service id="atlas_cli.helperset" class="Symfony\Component\Console\Helper\HelperSet" />

    <service id="atlas_cli.command.anonymize" class="AtlasCliBundle\Command\AnonymizeCommand" public="true">
        <tag name="console.command" />
        <call method="setHelperSet">
            <argument type="service" id="atlas_cli.helperset" />
        </call>
        <call method="setAnonymizeHelper">
            <argument type="service" id="atlas_cli.helper.anonymize" />
            <argument type="string">dbanonymizer</argument>
        </call>
        <call method="setDbConfigurationHelper">
            <argument type="service" id="atlas_cli.helper.dbconfiguration" />
            <argument type="string">dbconfiguration</argument>
        </call>
    </service>

    <service id="atlas_cli.command.schema" class="AtlasCliBundle\Command\SchemaCommand" public="true">
        <tag name="console.command" />
        <call method="setHelperSet">
            <argument type="service" id="atlas_cli.helperset" />
        </call>
        <call method="setDbConfigurationHelper">
            <argument type="service" id="atlas_cli.helper.dbconfiguration" />
            <argument type="string">dbconfiguration</argument>
        </call>
        <call method="setSchemadumpHelper">
            <argument type="service" id="atlas_cli.helper.schemadump" />
            <argument type="string">schemadump</argument>
        </call>
    </service>
</services>

As you can see I have configured 2 commands anonymize and schema. The commands are available when running app/console but the set methods (setDbConfigurationHelper for example) are never being called.

I use Symfony 2.1 but I searched the complete Symfony framework code on grep -ris "console\.command" * but that doesn't give any usefull result, either for Symfony 2.3.

Is the tag console.command not supported anymore? And if the answer is yes, what do you recommend to use for handling dependencies in my command classes?

Thanks!!

4

3 回答 3

3

The console.command tag in has been introduces in Symfony 2.4

For Symfony 2.3 and lower versions override Bundle::registerCommands to something like this:

<?php

namespace Acme\DemoBundle;

use Symfony\Component\Console\Application;

// ...

class AcmeDemoBundle extends Bundle
{
    public function registerCommands(Application $application)
    {
        $container = $application->getKernel()->getContainer();

        $application->add($container->get('atlas_cli.command.anonymize'));
        $application->add($container->get('atlas_cli.command.schema'));
    }
}
于 2013-05-23T20:59:13.337 回答
1

The quickest solution to have your services available is just extending Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand in your Command.

use Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand;

class AnonymizeCommand extends ContainerAwareCommand
{ 
   // ...

You will then have access to the container as usual and can pull in dependencies with

$myService = $this->container->get('service-name');

Yes i know injecting the whole container is usually not recommended for performance reasons and various others...

To debug tags within your container ( available since 2.2)

app/console container:debug --tags

debug a single tag with

app/console container:debug --tag=doctrine.event_listener

search for command related tags with grep ( or findstr if you are on windows )

app/console container:debug --tags | grep command

If you are using symfony2 you are not able to debug with these commands. In that case you should give the following 2 bundles a try. Both provide information about the container in the Profiler.

于 2013-05-23T10:23:40.707 回答
0

The component which searches for console.command and adds them is AddConsoleCommandPass:

public function build(ContainerBuilder $container) {
    parent::build($container); // TODO: Change the autogenerated stub
    $container->addCompilerPass(new AddConsoleCommandPass());
}

This is automatically done if you add the FrameworkBundle in your kernel.

于 2015-06-19T12:55:26.163 回答