在 symfony 中将非服务传递给自定义规范化的构造函数的正确方法是什么

what is the correct way to pass not services to the constructor of a custom normalize in symfony

我正在根据 Symfony 文档页面 https://symfony.com/doc/current/serializer/custom_normalizer.html 上的教程创建自己的 Normalizer,但我发现它不完整,因为它告诉您如何创建它,但没有应用它,这是第一点。

然后根据我在Symfony的一点经验,我试图猜测如何将数据传递给normalizer是正确的计算,我试图传递的数据不是services,可以是 String or a Request object,但是 none 这个数据让我,我真的需要理解或者我需要重构才能得到我想要的东西吗?

我把我的 normalizer 代码放在一起,以便很好地理解我在寻找什么。

标准化器:

<?php
namespace App\Serializer;

use App\Entity\Task;
use App\Traits\TaskControl;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class TaskNormalizer implements NormalizerInterface
{

  use TaskControl;

  private $normalizer;
  private $rangeDate;

  public function __construct(ObjectNormalizer $normalizer, $rangeDate )
  {
    $this->normalizer = $normalizer;
    $this->rangeDate  = $rangeDate;
  }


  public function normalize($task, $format = null, array $context = [])
  {
    $data = $this->normalizer->normalize($task, $format, $context);

    dd($this->rangeDate);

    $data['totalWork'] = $this->timeTask($task,$this->rangeDate);

    return $data;
  }

  public function supportsNormalization($task, $format = null, array $context = []): bool
  {
    return $task instanceof Task;
  }

}

应用规范化器: 传递来自对象 Request 的动态变量 $rangeDate。

$rangeDate   = $request->request->get('range','all');
$serializer = new Serializer([new TaskNormalizer($normalizer,$rangeDate)]);
$data = $serializer->normalize($attendances, null, ['attributes' => $attributes]);

这是我得到的错误:

Cannot autowire service "App\Serializer\TaskNormalizer": argument "$rangeDate" of method "__construct()" has no type-hint, you should configure its value explicitly.

您将不必明确声明您的服务...像这样应该可以解决问题:

## services.yml
 App\Serializer\TaskNormalizer :
            arguments:
                $normalizer: '@serializer.normalizer.object' ## check the alias ... 
                $rangeDate: '%range_date%'

请记住,为了依赖倒置原则,依赖接口比class更好。所以你应该考虑将构造函数更改为:

 ## your class
public function __construct(NormalizerInterface $normalizer, $rangeDate )
      {
        $this->normalizer = $normalizer;
        $this->rangeDate  = $rangeDate;
      }

为什么要将范围日期作为构造函数参数传递?

Normalizer 是一个服务依赖,rangeDate 是一个动态值。

您可以将其作为参数传递给 normalize 方法,而不是作为新参数或在上下文数组中传递:

$rangeDate  = $request->request->get('range','all');
$serializer = new Serializer([new TaskNormalizer($normalizer)]);
$data       = $serializer->normalize($attendances, null, ['attributes' => $attributes, 'rangeDate' => $rangeDate]);