Нужно ли пробрасывать Request в с сервис и/или в ValueObject или только конкретные типы?

В Symfony есть несколько подходов к передаче объекта Request в сервисы и ValueObject. Выбор определенного подхода зависит от конкретных требований и архитектурного дизайна вашего приложения.

1. Проброс объекта Request в сервис:
При использовании этого подхода, объект Request передается в сервис напрямую. Это позволяет сервису получать доступ к различным данным из запроса, таким как параметры маршрута, заголовки, данные формы и т.д. Зачастую это удобно, когда сервис нуждается в доступе к таким данным для выполнения своей работы. Однако, проброс объекта Request может привести к нарушению принципа единственной ответственности сервиса, так как теперь он становится зависимым от Symfony компонента и объекта Request.

Пример использования:

class MyService
{
    private $request;
    
    public function __construct(Request $request)
    {
        $this->request = $request;
    }
    
    public function doSomething()
    {
        // использование данных из объекта Request
        $param = $this->request->query->get('param');
        // ...
    }
}

2. Использование конкретных типов данных:
В этом подходе пробрасываются только конкретные типы данных из объекта Request, которые нужны сервису для выполнения его функциональности. Например, если сервису необходимы только параметры маршрута, то ему передают только эти параметры или объект RequestAttributeBag, который содержит параметры маршрута. Такой подход предоставляет большую гибкость и избавляет сервис от зависимости от Symfony компонента и объекта Request.

Пример использования:

class MyService
{
    private $routeParams;
    
    public function __construct(array $routeParams)
    {
        $this->routeParams = $routeParams;
    }
    
    public function doSomething()
    {
        // использование параметров маршрута
        $param = $this->routeParams['param'];
        // ...
    }
}

3. Использование ValueObject:
ValueObject - это объект, который инкапсулирует и представляет определенные данные из объекта Request. Этот подход позволяет абстрагировать сервис от зависимости от Symfony компонента и объекта Request и предоставляет более явные и понятные интерфейсы для работы с данными.

Пример использования:

class RouteParams
{
    private $params;
    
    public function __construct(array $params)
    {
        $this->params = $params;
    }
    
    public function getParam($name)
    {
        return $this->params[$name] ?? null;
    }
}

class MyService
{
    private $routeParams;
    
    public function __construct(RouteParams $routeParams)
    {
        $this->routeParams = $routeParams;
    }
    
    public function doSomething()
    {
        // использование параметров маршрута
        $param = $this->routeParams->getParam('param');
        // ...
    }
}

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