Symfony – Validator component with Dependency Injection

If you’re using the validation/validator component (eg. https://symfony.com/doc/current/components/validator.html) outside of the symfony framework and need to access a service within a custom constraint, here’s how to do it;

Create a ContainerConstraintValidatorFactory;

If you’re using the validation/validator component outside of the Symfony framework and need to access a service within a custom constraint (eg. http://symfony.com/doc/current/validation/custom_constraint.html), here’s how to do it;

Create a ContainerConstraintValidatorFactory;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;

class ContainerConstraintValidatorFactory extends ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface {
 private $container;
 
 public function __construct(ContainerInterface $container) {
  parent::__construct();
  $this->container = $container;
 }
 
 public function getInstance(Constraint $constraint) {
  if($this->container->has($constraint->validatedBy())) {
   return $this->container->get($constraint->validatedBy());
  }
 
  return parent::getInstance($constraint);
 }
}

From there, when you’re creating your ‘validator’, you’ll need to use your newly created factory;

$validatorBuilder = Validation::createValidatorBuilder();
$validatorBuilder->setConstraintValidatorFactory(
   new ContainerConstraintValidatorFactory($container)
);
$validator = $validatorBuilder->getValidator();

This will use your container to check if the constraint-validator class is registered … if so, it’ll be used, otherwise it’ll behave as normal.

Reference: https://stackoverflow.com/questions/40601866/how-to-configure-dependencies-on-custom-validator-with-symfony-components

Leave a Reply