如何通过动作的参数注入相同类型的不同服务?

How to inject different services of the same type via action's parameters?

我有一个带有两个动作的简单控制器。它们具有不同的输出格式,因此我想在操作参数中注入不同的 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));
    }
}

here所述,如果您对同一类型的服务有多个实现,您可以在配置中声明不同的类型,并将每个类型绑定到不同的参数名称:

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)
{
}