【问题标题】:How to inject Symfony Serializer to the controller properly?如何正确地将 Symfony Serializer 注入控制器?
【发布时间】:2019-07-14 15:21:49
【问题描述】:

我在将 Symfony Serializer 注入控制器时遇到问题。 这是我想要实现的行为的一个工作示例:

public function someAction(): Response
{
    $goodViews = //here I get an array of Value Objects or DTO's ;

    $serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);

    // normalize gives me a proper array for serialization
    return $this->json(
         $serializer->normalize($goodViews)
    );
}

但是现在我需要将使用依赖注入的 Serializer 直接创建更改为控制器构造函数或操作。我认为,另一种方法是创建将 ObjectNormalizer 和 JsonEncoder 作为参数的服务,然后创建一个 Serializer,然后以特殊方法规范化对象数组并返回结果。但我无法弄清楚如何在 service.yml 中创建序列化程序或正确描述服务依赖项。 Symfony 文档也可以获得简单的序列化器服务,或者像我在代码示例中那样手动创建它。

我想从操作中的服务容器获取序列化程序服务(使用 $this->get('serializer'))或使用 NormalizerInterface 将其注入控制器构造函数(我主要需要规范化对象数组),但是这个注入的序列化程序出现了这样的错误:

"message": "Cannot normalize attribute \"options\" 因为 注入的序列化程序不是规范化程序”,“类”: "Symfony\Component\Serializer\Exception\LogicException",

所以我想,它没有按照我手动创建序列化程序的方式进行配置。

我们的 Symfony 版本是 3.4 感谢您的关注。

【问题讨论】:

    标签: symfony dependency-injection serialization


    【解决方案1】:

    我的问题的决定有点棘手。 ObjectNormalizer 被自定义规范化器覆盖(在自定义服务定义中带有 decorate 部分 - 请参阅https://symfony.com/doc/3.4/service_container/service_decoration.html)。这就是为什么在框架预配置的 Symfony 序列化器中我得到了我们自定义的序列化器,这产生了一个错误:

    无法规范化属性 \"options\" 因为注入的序列化程序 不是规范化器

    所以我用 ObjectNormalizer 创建了一个新的序列化器服务:

    new_api.serializer_with_object_normalizer:
        class: Symfony\Component\Serializer\Serializer
        arguments:
            0:
                - "@our_custom_serviec_which_override_object_normalizer.inner"
            1:
                - "@serializer.encoder.json"
    

    【讨论】:

      【解决方案2】:
      public function someAction(SerializerInterface $serializer): Response // Add serializer as an argument
      {
          $goodViews = //here I get an array of Value Objects or DTO's ;
      
          // normalize gives me a proper array for serialization
          return $this->json(
               $serializer->normalize($goodViews)
          );
      }
      

      services.yml

      # *Bundle/Resources/services.yaml
      services:
          YourNamespace/*Bundle/Controller/YourController:
              tags: [ 'controller.service_arguments' ]
      

      试试看,然后告诉我们。这应该能让你继续前进,但有更好的方法可以配置你的项目。在这里查看有关将控制器用作服务以及如何自动连接它们的更多信息。

      https://symfony.com/doc/3.4/service_container.html

      https://symfony.com/doc/3.4/serializer.html

      【讨论】:

      • 为什么要重新创建$serializer
      猜你喜欢
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2014-06-12
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 2011-11-27
      相关资源
      最近更新 更多