Api platform.com 如何在contstruct中注入服务?

Api platform.com 如何在contstruct中注入服务?,api-platform.com,Api Platform.com,我想在\uuu-construct中插入Symfony\Component\Security\Core\Security,以获取当前用户。它需要我来使用@uniquenity验证程序: <?php declare(strict_types=1); namespace App\Entity; use ApiPlatform\Core\Annotation\ApiResource; use Symfony\Bridge\Doctrine\Validator\Constraints\Uni

我想在
\uuu-construct
中插入
Symfony\Component\Security\Core\Security
,以获取当前用户。它需要我来使用
@uniquenity
验证程序:

<?php

declare(strict_types=1);

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\Security;
//...


/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass="App\Repository\SimpleEntityRepository")
 * @UniqueEntity(fields={"foo", "user"})
 */
class SimpleEntity
{

    //...

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

    public function __construct(Security $security)
    {
        $this->user = $security->getUser();
    }

    //...
}


Symfony可以将服务注入其他服务的构造函数,但不能注入实体的构造函数

通常,在实体上设置当前用户将通过修饰apip的内置DataPersister来完成。然而,持久化通常发生在处理请求的末尾,而验证则发生在更早的时候。因此,验证器不会看到稍后由持久化程序设置的用户。因此,您需要在进行验证之前,在流程的早期设置用户。这可以通过一种方法来实现。这是一个服务,因此您可以注入安全服务:

// api/src/Serializer/SimpleEntityDenormalizer

namespace App\Serializer;

use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use App\Entity\SimpleEntity;

final class SimpleEntityDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface
{
    private $decorated;
    private $security;

    public function __construct(DenormalizerInterface $decorated, Security $security)
    {
        $this->decorated = $decorated;
        $this->security = $security;
    }

    public function supportsDenormalization($data, string $type, string $format = null, array $context = [])
    {
        if ($type !== SimpleEntity::class) return false;

        return $this->decorated->supportsDenormalization($data, $type, $format, $context);
    }

    public function denormalize($data, string $type, string $format = null, array $context = [])
    {
        $object = $this->decorated->denormalize($data, $type, $format, $context);

        if (null === $object->getUser()) {
            $object->setUser($this->security->getUser());
        }

        return $object;
    }

    public function setSerializer(SerializerInterface $serializer)
    {
        if($this->decorated instanceof SerializerAwareInterface) {
            $this->decorated->setSerializer($serializer);
        }
    }
}
将以下内容添加到api/config/services.yaml:

'App\Serializer\SimpleEntityDenormalizer':
    arguments: 
    $decorated: '@api_platform.jsonld.normalizer.item' ]
这不会取代装饰过的服务,而是添加了一个新的服务