简体   繁体   中英

Symfony 3 - how to inject the validator into a service?

I try to inject the validator into my service - but I don't find it:

mybundle.service.supplier:
     class: AppBundle\Service\SupplierService
     calls:
        - [setValidator, ['@validator']]

the @validator is not the expected RecursiveValidator http://api.symfony.com/3.1/Symfony/Component/Validator/Validator/RecursiveValidator.html - the @validator is an interface.

So how can I inject the validator into my service?

This is what I want:

<?php

namespace AppBundle\Service;


use AppBundle\Entity\Supplier;
use AppBundle\Helper\EntityManagerTrait;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Validator\Validator\RecursiveValidator;

/**
 * Class SupplierService
 * @package AppBundle\Service
 */
class SupplierService
{
    use EntityManagerTrait;

   /** @var RecursiveValidator $validator */
    protected $validator;

    /**
     * @return RecursiveValidator
     */
    public function getValidator()
    {
        return $this->validator;
    }

    /**
     * @param RecursiveValidator $validator
     * @return SupplierService
     */
    public function setValidator($validator)
    {
        $this->validator = $validator;

        return $this;
    }


    public function addSupplier($data)
    {
        $supplier = new Supplier();
        $validator = $this->getValidator();
        $errors = $validator->validate($supplier);

    }
}

@validator is an interface.

This does not make sense. If it would be an interface, there could not be an instacne of Validator service. Yes, it does implement ValidatorInterface , but it is not it.

On the other hand, I am sure you would get an instance of RecursiveValidator . See my analyses:

  • Check the validator definition in Symfony's XML:

     <service id="validator" class="Symfony\\Component\\Validator\\Validator\\ValidatorInterface"> <factory service="validator.builder" method="getValidator" /> </service> 
  • Check the definition of validator.builder factory service:

     <service id="validator.builder" class="Symfony\\Component\\Validator\\ValidatorBuilderInterface"> <factory class="Symfony\\Component\\Validator\\Validation" method="createValidatorBuilder" /> <call method="setConstraintValidatorFactory"> <argument type="service" id="validator.validator_factory" /> </call> <call method="setTranslator"> <argument type="service" id="translator" /> </call> <call method="setTranslationDomain"> <argument>%validator.translation_domain%</argument> </call> </service> 
  • Check the factory Symfony\\Component\\Validator\\Validation::createValidatorBuilder . It returns an instance of ValidatorBuilder

  • Finally, check the ValidatorBuilder::getValidator() . It ends with the following:

     return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $this->initializers); 

So, you will get the correct instance ( RecursiveValidator ).

Hope this helps...

In symfony 3.4 simply like this worked:

Config:

stl.transaction.import.writer.insurance_company:
        class: STL\TransactionBundle\Import\Writer\InsuranceCompanyWriter
        public: false
        arguments:
            - '@validator'

Your service:

use Symfony\Component\Validator\Validator\ValidatorInterface;
// ...
public function __construct(
        ValidatorInterface $validator,
    ) {
        $this->validator = $validator;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM