-1

Symfony 2.8

Being in a Service called from a Command, Is there any way to execute/invoke a Controller Action as a Process Object? Or do I have to covert that Controller Action into a Command in order to be called by a Process?

I need to execute iterative BL (business logic) elements, already coded into Controller Actions.

The invoking chain is:

Scheduled Command --> Service Container --> N Processes or whatever with BL.

Service must control/monitor the Processes execution. (start, run, stop, etc..)

Any other way?

Cheers!!

NorthmaN
  • 105
  • 2
  • 11
  • 1
    Even if it was possible, it would be a big mistake from design point of view. Controllers are meant to process HTTP request, while services may be used also in other contexts like CLI. Also, you should not have any business logic in controllers, so there shouldn't be any reason to call them from any other place in your app. – Jakub Matczak Jul 14 '20 at 13:52
  • 1
    The basic idea is extract to code into it's own service and then inject the service into either an action or a command as needed. – Cerad Jul 14 '20 at 13:53
  • Understood. It means I have to move Controller BL into a new Service. That will be invoke by as many Commands as needed that will be Processes (try to do it asynchronously). Invoking Chain: Scheduled Command --> Service Container (evaluate elements (N) to apply BL) --> N Processes --> N Commands --> N Service Containers (BL) Thanks!! – NorthmaN Jul 14 '20 at 14:19

1 Answers1

1

In order to avoid duplicating the business logic from the controller action, create a new service and declare it into the service container, you specified you are using symfony 2.8 so there's no autowire feature available and you need to declare it manually

services:
    app.custom_service:
        class:     AppBundle\Service\BusinessLogicService
        arguments: []

Then you can use it in your controller injecting it via (dependency injection) or simply call it from the container service

// the container will instantiate a new BusinessLogicService()
$service = $this->container->get('app.custom_service');

For the command, you can implement the ContainerAwareInterface and again call your service from the service container

ex:

class BusinessLogicCommand extends Command implements ContainerAwareInterface
{

    public function getBusinessLogicService()
    {
        return $this->getContainer()->get('app.custom_service');
    }
}
rnenciu
  • 368
  • 4
  • 13
  • 1
    Is it the same that extending from ContainerAwareCommand? Isn't it? Because implementing ContainerAwareInterface means coding setContainer(ContainerInterface $container = null) function. – NorthmaN Jul 14 '20 at 14:38
  • 1
    that's even better, extending ContainerAwareCommand will keep cleaner, preventing glue coding the setContainer function – rnenciu Jul 14 '20 at 21:52
  • Service as a Command or Viceversa --> Problems/conflict with the Service Constructor (extending ContainerAwareCommand) in order to get its injected service arguments (@doctrine.orm.entity_manager,@mailer,@templating). Command not defined... – NorthmaN Jul 15 '20 at 17:36
  • services: report.send: class: My\ReportsBundle\Command\ReportSendCommand arguments: [@doctrine.orm.entity_manager,@mailer,@templating] – NorthmaN Jul 15 '20 at 17:37
  • protected function execute(InputInterface $input, OutputInterface $output) { $argument = $input->getArgument('argument'); $container = $this->getContainer()->get('report.send'); $container->send(array($argument)); } public function __construct(EntityManager $em,\Swift_Mailer $mailer, \Symfony\Bridge\Twig\TwigEngine $template) { parent::__construct(); $this->em = $em; $this->mailer = $mailer; $this->template = $template; } – NorthmaN Jul 15 '20 at 17:38
  • It means a Service Container can't be a Command itself. SO, I have to do it separately, a Command that get/invoke a Service with its #parameters. – NorthmaN Jul 15 '20 at 17:56