0

I have a SearchManager service which can execute search with the specified engine.

// controller

public function searchAction(RequestStack $requestStack, SearchManager $searchManager): Response
{
    // code

    $engine = new ElasticsearchEngine();
    $searchManager->setEngine($engine)->search($requestStack);
    // code
}

class SearchManager {

    private $engine;

    public function __construct(){
    }

    public function setEngine(EngineInterface $engine)
    {
        $this->engine = $engine;
        return $this->engine;
    }
}

class ElasticsearchEngine implement EngineInterface 
{
    public function search(RequestStack $requestStack)
    {
        // Here I build the request
        $elasticsearchCommand['from'] = 0;
        $elasticsearchCommand['size'] = 100;
        $elasticsearchCommand['query']['bool']['must'] = ["match_all" => new \stdClass()];
        // so on
        // To continue building the query I need to parse posted data and get elasticsearch formatted query so I use a class to do that
        $formParser = new FormParser($requestStack);
        $elasticsearchCommand['query']['bool']['filter']['bool']['filter'] = $formParser->getFormattedQuery();
    }
}

In FormParser I need for some reasons some app parameter. But all these class are instantiate explicitly and I can't get benefits from auto wiring. How can access ParameterbarInterface without injecting it where it's not needed ? (cascading injection)

yivi
  • 42,438
  • 18
  • 116
  • 138
akio
  • 851
  • 9
  • 29
  • You can't. If you need the ParameterBag in FormParser, you need to inject it somehow. If you are instantiating it manually instead of getting if from the container, then you'll have to inject it in the service that instantiates FormParser. – yivi Jan 27 '22 at 12:44
  • What's `FormParser` anyway? Is it your code? Why can't you create a service that needs `RequestStack` and `ParamterBagInterface`, and inject **that** into `EngineInterface`? – yivi Jan 27 '22 at 12:45
  • Yes FormParser is my own service that build query depending on the engine – akio Jan 27 '22 at 13:06
  • So just make the service depend on `RequestStack` and `ParameterBagInterface`, and get it from the container instead of instantiating it manually. That's all there is to it. – yivi Jan 27 '22 at 13:08
  • Get it from controller then inject it into `ElasticsearchEngine` ? – akio Jan 27 '22 at 13:22
  • No, use autowiring as with any other service. `FormParser` would depend on `RequestStack` and `ParameterBagInterface`, and `ElasticsearchEngine` would in turn depend on `FormParser`. And `ElasticsearchEngine` shouldn't be instantiated manually either, but get it via autowiring as well. – yivi Jan 27 '22 at 13:28
  • `ElasticsearchEngine` should be instantiated manually because engine could be another kind like `MysqlEngine` no ? Because `SearchEngineManager` need an instance of `EngineInterface` – akio Jan 27 '22 at 13:38
  • thx but all provided links not helping me – akio Jan 27 '22 at 13:48
  • They will, once you take some time to understand they apply specifically to your issue. You need to create several services that need to be autowired, and not instantiate them manually. – yivi Jan 27 '22 at 13:53
  • no they won't, in controller `searchAction(EngineInterface $engine)`Symfony not knows if `ElasticsearchEngine` or `MysqlEngine` or `WhateverEngine` should be instantiate – akio Jan 27 '22 at 13:55
  • Exactly, which is why the linked dupes show you how to inject a group of closely related services. – yivi Jan 27 '22 at 14:13

0 Answers0