symfony4 autowiring Автозагрузка сервисов и параметров. Как получать сервисы и параметры в классах (autowiring, bind parameters)

В более стрых версиях Symfony для загрузки сервисов и параметром приходилось пользоваться контейнером: вызывать сначала его, а потом уже доставать из него то, что необходимо.

Начиная с версии 3.4 можно загружать всё автоматически, укладывая экземпляры классов (для сервисов) или непосредственные значения (для параметров) в поля класса, использующего их.

Сервисы

Теперь дополнительно описывать их в services.yaml не требуется, просто создаём экземпляр сервиса в классе и с помощью него вызываем методы:

<?php

namespace App\Controller;

use App\Repository\InvestmentRepository;

class AgreementController extends Controller
{
    /**
     * @var InvestmentRepository
     */
    private $investmentRepository;

    /**
     * @param InvestmentRepository $investmentRepository
     */
    public function __construct(InvestmentRepository $investmentRepository)
   {
        // так создаём экземпляр сервиса (в данном случае это репозиторий)
        $this->investmentRepository = $investmentRepository;
    }

    /**
     * @Route("/investment/agreement", name="create_agreement", methods={"POST"})
     *
     * @param int $investmentId
     *
     * @return Response
     */
    public function createAgreement(int $investmentId): Response
   {
         // так вызываем методы
         $investment = $this->investmentRepository->getById($investmentId);
         // ...
    }
}

Параметры

Чтобы таким же способом загрузить параметр в классе, его необходимо добавить в список автозагружаемых параметров bind в services.yaml:

parameters:
    numberOfLinesPerPage: 1

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.
        bind:
            $numberOfLinesPerPage: '%numberOfLinesPerPage%'

Теперь можно использовать параметр так:

<?php

namespace App\Helpers;

use App\DTO\PageData;

class PaginationHelper
{
    /**
     * @var int
     */
    private $numberOfLinesPerPage;

    /**
     * @param int $numberOfLinesPerPage
     */
    public function __construct(int $numberOfLinesPerPage)
    {
        $this->numberOfLinesPerPage = $numberOfLinesPerPage;
    }
    
    /**
     * @return PageData
     */
    public function getPageData(): PageData
    {
        numberOfLinesPerPage = $this->numberOfLinesPerPage;
        // ...
    }
}

Источники