2016-11-15 104 views
0

我正在使用Symfony验证程序Symfony服务容器在一个项目中,但不是完整的Symfony框架。如何使用Symfony组件配置自定义验证器的依赖关系?

我写了一个自定义验证器,需要一些依赖项作为构造函数参数提供。

Symfony Documentation描述了一种将验证器配置为服务的方法,该方法已成功完成。但是,这使得使用validator.constraint_validator服务标签,我怀疑它们粘在一起。

此服务标签似乎是具体的使用完整的Symfony框架时 - (意料之中)的Symfony验证是不是神奇加载我自定义的验证,当我加入这个标签

所以,我怎么可以链接验证和服务容器组件?或者是否有任何其他策略让Symfony验证器加载我的客户验证器的依赖关系?

回答

1

你是对的,这个标签(validator.constraint_validator)由编译器处理 - 从Symfony/FrameworkBundle传递。 如果你不想使用这个包,但你想链接DI容器和验证器,你应该重新实现这个过程。

首先,我们需要一个ConstraintValidatorFactoryInterface的实例。 Default implementation只是寻找一个类,其名称由validatedBy()方法的约束返回。 Implementation from FrameworkBundle将validatedBy()的结果视为服务标识符/或标签别名,并从容器中获取此服务。我们的实现应该做这样的事情:

use Symfony\Component\DependencyInjection\ContainerInterface; 

use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; 
use Symfony\Component\Validator\Constraint; 

class ContainerConstraintValidatorFactory implements ConstraintValidatorFactoryInterface 
{ 
    private $container; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    public function getInstance(Constraint $constraint) 
    { 
     // Simplified implementation, just for example: 
     return $this->container->get($constraint->validatedBy()); 
    } 
} 

例如,假设我们有一些依赖一些自定义的验证约束和验证器类:

use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\ConstraintValidator; 

class CustomConstraint extends Constraint 
{ 
    public $message = 'Oops!'; 

    public function validatedBy() 
    { 
     return 'validator.custom'; 
    } 
} 

class CustomConstraintValidator extends ConstraintValidator 
{ 
    private $dependency; 

    public function __construct($dependency) 
    { 
     $this->dependency = $dependency; 
    } 

    public function validate($value, Constraint $constraint) 
    { 
     if (rand() % 2 === 0) { 
      $this->context 
       ->buildViolation($constraint->message) 
       ->addViolation(); 
     } 
    } 
} 

接下来我们登记约束验证为服务与ID相同来自相关约束对象的validatedBy()方法的结果。我们通过这个工厂创建与容器相关的验证器服务的实例。所有的约束验证器都以相同的方式注册。

use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\Validator\Validation; 

$container = new ContainerBuilder(); 
$container->register(
    'validator.custom', 
    new CustomConstraintValidator('Some dependency value') 
); 

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

$violations = $validator->validate('test value', [ 
    new CustomConstraint() 
]); 

它的工作原理,但我建议考虑使用FrameworkBundle不要重新发明轮子。您可以将其配置为仅使用您需要的东西。

相关问题