Symfony2有条件服务声明

sl0*_*815 6 service mocking symfony behat

我目前正在尝试找到一个可靠的解决方案来动态更改Symfony2服务的依赖关系.详细信息:我有一个使用HTTP驱动程序与外部API通信的服务.

class myAwesomeService
{
    private $httpDriver;

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

    public function transmitData($data)
    {
        $this->httpDriver->dispatch($data);
    } 
}
Run Code Online (Sandbox Code Playgroud)

在CI上运行Behat测试时,我想使用httpMockDriver而不是真正的驱动程序,因为外部API可能会崩溃,缓慢甚至破坏,我不想破坏构建.

目前我正在做这样的事情:

<?php
namespace MyAwesome\TestBundle\DependencyInjection;

class MyAwesomeTestExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new       
                     FileLocator(__DIR__.'/../Resources/config'));
        $environment = //get environment
        if ($environment == 'test') {
            $loader->load('services_mock.yml');         
        } else {
            $loader->load('services.yml');          
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这现在有效,但肯定会打破.那么,是否有更优雅/可靠的方式来动态更改HTTPDriver?

sl0*_*815 8

我终于找到了一个看起来很稳固的解决方案.从Symfony 2.4开始,您可以使用表达式语法:使用表达式语言

所以我用这种方式配置了我的服务.

service.yml
parameters:
  httpDriver.class:       HTTP\Driver\Driver
  httpMockDriver.class:   HTTP\Driver\MockDriver
  myAwesomeService.class: My\Awesome\Service
service:
  myAwesomeService:
    class:        "%myAwesomeService.class%"
    arguments:    
      - "@=service('service_container').get('kernel.environment') == 'test'? service('httpMockDriver) : service('httpDriver)"
Run Code Online (Sandbox Code Playgroud)

这适合我.

  • 该链接已弃用.这是正确的:http://symfony.com/doc/current/service_container/expression_language.html (2认同)