【发布时间】:2016-07-19 15:26:33
【问题描述】:
我需要根据特定配置使用特定的验证器来验证 JSON 消息。
我已将验证器和约束定义为服务:
services:
validator.constraint.message.country_code:
class: RenamedBundle\Validator\Constraints\CountryCode
arguments: ...
validator.constraint.message.price_comma:
class: RenamedBundle\Validator\Constraints\PriceComma
arguments: ...
message.validator:
class: RenamedBundle\Service\Validator\MessageValidatorService
arguments: ['@validator']
calls:
- [addConstraint, ['@validator.constraint.message.country_code']]
- [addConstraint, ['@validator.constraint.message.price_comma']]
在DtoValidatorService 中,我使用约束列表调用validate()。
问题...挑战是相同的 JSON 消息仅需要列表中的少数验证器进行验证,这取决于消息属性,即。对于波兰,我想验证所有浮点值(在波兰分隔符是“,”,而不是“。”)。我已经尝试通过config.yml 做到这一点。
renamed:
pritners:
warehouse_wa:
characteristic:
country: 'pl'
source: 'hq-pl'
validators:
- '@validator.constraint.message.country_code'
- '@validator.constraint.message.price_comma'
warehouse_ny:
characteristic:
country: 'us'
source: 'hq-us'
validators:
- '@validator.constraint.message.country_code'
我添加了扩展:
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*
* @throws \RuntimeException
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('renamed');
$rootNode
->children()
->arrayNode('printers')
->useAttributeAsKey('name')
->prototype('array')
->children()
->arrayNode('characteristic')
->children()
->scalarNode('country')->end()
->scalarNode('source')->end()
->end()
->end()
->end()
->children()
->arrayNode('validators')
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}
}
class RenamedExtension extends Extension
{
/**
* {@inheritDoc}
* @throws \Exception
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$container->setParameter('printers', $config['printers']);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
}
}
此配置有效,但问题是当我将 '%printers%' 参数传递给服务时,我收到服务名称列表:
Array
(
[0] => @validator.constraint.message.country_code
)
但是当我通过约束时,我得到了对象。
array(1) {
[0] =>
class RenamedBundle\Validator\Constraints\CountryCode#688 (5) {
...
}
}
我现在处于死胡同。如何参数化打印机配置并避免传递内联/硬代码验证器类名。不允许在参数部分调用服务。在配置中调用它们为我提供了额外的控制和验证。 也许有人有更好的解决方案?
编辑: 根据@Artur Vesker 的建议,我更改了扩展加载方法的实现。
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$printers = [];
foreach ($config['printers'] as $printerName => $printerConfig) {
$constraints = [];
foreach($printerConfig['valdiators'] as $constraintName) {
$constraintName = ltrim($constraintName, '@');
$constraints[] = new Reference($constraintName);
}
$printerConfig['valdiators'] = $constraints;
$printers[$printerName] = $printerConfig;
}
$container->setParameter('printers', $printers);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
}
尝试构建缓存我得到了:
Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
You cannot dump a container with parameters that contain references to other services
看起来我的方法在 symfony 世界中是不允许的;]
【问题讨论】:
标签: validation symfony dependency-injection