Skip to content

Commit

Permalink
feature #25288 [DI][FrameworkBundle] Add PSR-11 "ContainerBag" to acc…
Browse files Browse the repository at this point in the history
…ess parameters as-a-service (nicolas-grekas, sroze)

This PR was merged into the 4.1-dev branch.

Discussion
----------

[DI][FrameworkBundle] Add PSR-11 "ContainerBag" to access parameters as-a-service

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17160
| License       | MIT
| Doc PR        | -

There is one thing that prevents us from not injecting the container: access to the parameter bag.
This PR fixes this limitation by providing a PSR-11 `ContainerBagInterface` + related implementation, and wiring it as a service that ppl can then also autowire using the new interface as a type hint, or `ParameterBagInterface`.

Needed to complete e.g. #24738

Commits
-------

561cd7e Add tests on the ContainerBag
0e18d3e [DI][FrameworkBundle] Add PSR-11 "ContainerBag" to access parameters as-a-service
  • Loading branch information
nicolas-grekas committed Dec 8, 2017
2 parents 7744e8f + 561cd7e commit b56ab7b
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Expand Up @@ -4,7 +4,8 @@ CHANGELOG
4.1.0
-----

* allowed to pass an optional `LoggerInterface $logger` instance to the `Router`
* Allowed to pass an optional `LoggerInterface $logger` instance to the `Router`
* Added a new `parameter_bag` service with related autowiring aliases to acces parameters as-a-service

4.0.0
-----
Expand Down
Expand Up @@ -35,6 +35,8 @@
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand Down Expand Up @@ -111,6 +113,12 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('services.xml');
$loader->load('fragment_renderer.xml');

if (!interface_exists(ContainerBagInterface::class)) {
$container->removeDefinition('parameter_bag');
$container->removeAlias(ContainerBagInterface::class);
$container->removeAlias(ParameterBagInterface::class);
}

if (class_exists(Application::class)) {
$loader->load('console.xml');

Expand Down
Expand Up @@ -7,6 +7,12 @@
<services>
<defaults public="false" />

<service id="parameter_bag" class="Symfony\Component\DependencyInjection\ParameterBag\ContainerBag">
<argument type="service" id="service_container" />
</service>
<service id="Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface" alias="parameter_bag" />
<service id="Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface" alias="parameter_bag" />

<service id="event_dispatcher" class="Symfony\Component\EventDispatcher\EventDispatcher" public="true">
<tag name="container.hot_path" />
</service>
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/DependencyInjection/CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@ CHANGELOG
-----

* added support for variadics in named arguments
* added PSR-11 `ContainerBagInterface` and its `ContainerBag` implementation to access parameters as-a-service

4.0.0
-----
Expand Down
Expand Up @@ -11,12 +11,14 @@

namespace Symfony\Component\DependencyInjection\Exception;

use Psr\Container\NotFoundExceptionInterface;

/**
* This exception is thrown when a non-existent parameter is used.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ParameterNotFoundException extends InvalidArgumentException
class ParameterNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
{
private $key;
private $sourceId;
Expand Down
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Container;

/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ContainerBag extends FrozenParameterBag implements ContainerBagInterface
{
private $container;

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

/**
* {@inheritdoc}
*/
public function all()
{
return $this->container->getParameterBag()->all();
}

/**
* {@inheritdoc}
*/
public function get($name)
{
return $this->container->getParameter($name);
}

/**
* {@inheritdoc}
*/
public function has($name)
{
return $this->container->hasParameter($name);
}
}
@@ -0,0 +1,55 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\ParameterBag;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;

/**
* @author Nicolas Grekas <p@tchwork.com>
*/
interface ContainerBagInterface extends ContainerInterface
{
/**
* Gets the service container parameters.
*
* @return array An array of parameters
*/
public function all();

/**
* Replaces parameter placeholders (%name%) by their values.
*
* @param mixed $value A value
*
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
*/
public function resolveValue($value);

/**
* Escape parameter placeholders %.
*
* @param mixed $value
*
* @return mixed
*/
public function escapeValue($value);

/**
* Unescape parameter placeholders %.
*
* @param mixed $value
*
* @return mixed
*/
public function unescapeValue($value);
}
@@ -0,0 +1,65 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\Tests\ParameterBag;

use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBag;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class ContainerBagTest extends TestCase
{
/** @var ParameterBag */
private $parameterBag;
/** @var ContainerBag */
private $containerBag;

public function setUp()
{
$this->parameterBag = new ParameterBag(array('foo' => 'value'));
$this->containerBag = new ContainerBag(new Container($this->parameterBag));
}

public function testGetAllParameters()
{
$this->assertSame(array('foo' => 'value'), $this->containerBag->all());
}

public function testHasAParameter()
{
$this->assertTrue($this->containerBag->has('foo'));
$this->assertFalse($this->containerBag->has('bar'));
}

public function testGetParameter()
{
$this->assertSame('value', $this->containerBag->get('foo'));
}

/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
*/
public function testGetParameterNotFound()
{
$this->containerBag->get('bar');
}

public function testInstanceOf()
{
$this->assertInstanceOf(FrozenParameterBag::class, $this->containerBag);
$this->assertInstanceOf(ContainerBagInterface::class, $this->containerBag);
$this->assertInstanceOf(ContainerInterface::class, $this->containerBag);
}
}

0 comments on commit b56ab7b

Please sign in to comment.