Как внедрить разные сервисы одного типа через параметры действия? - PullRequest
2 голосов
/ 18 июня 2020

У меня простой контроллер с двумя действиями. У них другой формат вывода, поэтому я хочу добавить разные реализации Formatter в параметры действия. Есть ли правильный способ сделать это?

class ProductController
{
    private ProductManager $productManager;

    public function __construct(ProductManager $productManager)
    {
        $this->productManager = $productManager;
    }

    public function search(Request $request, Formatter $formatter)
    {
        $query = $request->get('q');
        $response = $this->productManager->search($query);

        return new JsonResponse($formatter->format($response));
    }

    public function suggest(Request $request, Formatter $formatter)
    {
        $query = $request->get('q');
        $response = $this->productManager->suggest($query);

        return new JsonResponse($formatter->format($response));
    }
}

1 Ответ

3 голосов
/ 18 июня 2020

Как объяснено здесь , если у вас есть несколько реализаций одного и того же типа сервиса, вы можете объявить разные типы в конфигурации и привязать каждый тип к другому имени параметра:

services:
    # ...

    # Both these services implement the "Formatter" interface
    App\Util\SearchyFormatter: ~
    App\Util\SuggestyFormatter: ~

    # When you want to use the "SuggestyFormatter" implementation, you
    # type-hint for 'Formatter $suggestyFormatter'
    App\Util\Formatter $suggestyFormatter: '@App\Util\SuggestyFormatter'

    # This is the default implementation for the type
    App\Util\Formatter: '@App\Util\SearchyFormatter'

С помощью этого вы можете:

// since the parameter name does not match any of the existing declarations,
// the default will be used: App\Util\SearchyFormatter
public function search(Request $request, Formatter $formatter)
{
}

// and for this one, App\Util\SuggestyFormatter will be used instead
public function suggest(Request $request, Formatter $suggestyFormatter)
{
}
...