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

php, symfony, validation

Solution

@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...

Problem

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); } } ```

Original source