[DependencyInjection] made an optimization on dumped DIC

When dumping a Container, and if it is frozen, we use a plain
PHP array for parameters instead of a ParameterBag.
This commit is contained in:
Fabien Potencier 2011-01-30 15:06:45 +01:00
parent 2d69369c69
commit b6f400a2bc
4 changed files with 129 additions and 117 deletions

View File

@ -71,14 +71,22 @@ class PhpDumper extends Dumper
'base_class' => 'Container',
), $options);
return
$this->startClass($options['class'], $options['base_class']).
$this->addConstructor().
$code = $this->startClass($options['class'], $options['base_class']);
if ($this->container->isFrozen()) {
$code .= $this->addFrozenConstructor();
} else {
$code .= $this->addConstructor();
}
$code .=
$this->addServices().
$this->addDefaultParametersMethod().
$this->addInterfaceInjectors().
$this->endClass()
;
return $code;
}
protected function addInterfaceInjectors()
@ -515,7 +523,7 @@ EOF;
protected function startClass($class, $baseClass)
{
$bagClass = $this->container->isFrozen() ? 'FrozenParameterBag' : 'ParameterBag';
$bagClass = $this->container->isFrozen() ? '' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;';
return <<<EOF
<?php
@ -524,7 +532,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\\$bagClass;
$bagClass
/**
* $class
@ -539,8 +547,6 @@ EOF;
protected function addConstructor()
{
$bagClass = $this->container->isFrozen() ? 'FrozenParameterBag' : 'ParameterBag';
$code = <<<EOF
/**
@ -548,7 +554,7 @@ EOF;
*/
public function __construct()
{
parent::__construct(new $bagClass(\$this->getDefaultParameters()));
parent::__construct(new ParameterBag(\$this->getDefaultParameters()));
EOF;
@ -561,6 +567,42 @@ EOF;
$code .= <<<EOF
}
EOF;
return $code;
}
protected function addFrozenConstructor()
{
$code = <<<EOF
/**
* Constructor.
*/
public function __construct()
{
\$this->parameters = \$this->getDefaultParameters();
\$this->services =
\$this->scopedServices =
\$this->scopeStacks = array();
\$this->set('service_container', \$this);
EOF;
$code .= "\n";
if (count($scopes = $this->container->getScopes()) > 0) {
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n";
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
} else {
$code .= " \$this->scopes = array();\n";
$code .= " \$this->scopeChildren = array();\n";
}
$code .= <<<EOF
}
EOF;
return $code;
@ -574,7 +616,43 @@ EOF;
$parameters = $this->exportParameters($this->container->getParameterBag()->all());
return <<<EOF
$code = '';
if ($this->container->isFrozen()) {
$code .= <<<EOF
/**
* {@inheritdoc}
*/
public function getParameter(\$name)
{
\$name = strtolower(\$name);
if (!array_key_exists(\$name, \$this->parameters)) {
throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', \$name));
}
return \$this->parameters[\$name];
}
/**
* {@inheritdoc}
*/
public function hasParameter(\$name)
{
return array_key_exists(strtolower(\$name), \$this->parameters);
}
/**
* {@inheritdoc}
*/
public function setParameter(\$name, \$value)
{
throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
}
EOF;
}
$code .= <<<EOF
/**
* Gets the default parameters.
@ -587,6 +665,8 @@ EOF;
}
EOF;
return $code;
}
protected function exportParameters($parameters, $indent = 12)

View File

@ -27,9 +27,6 @@ ClassCollectionLoader::load(array(
'Symfony\\Component\\DependencyInjection\\Container',
'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface',
'Symfony\\Component\\DependencyInjection\\ContainerAware',
'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface',
'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag',
'Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag',
'Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface',
'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',

View File

@ -219,109 +219,6 @@ class ContainerAware implements ContainerAwareInterface
}
}
}
namespace Symfony\Component\DependencyInjection\ParameterBag
{
interface ParameterBagInterface
{
function clear();
function add(array $parameters);
function all();
function get($name);
function set($name, $value);
function has($name);
}
}
namespace Symfony\Component\DependencyInjection\ParameterBag
{
class ParameterBag implements ParameterBagInterface
{
protected $parameters;
public function __construct(array $parameters = array())
{
$this->parameters = array();
$this->add($parameters);
}
public function clear()
{
$this->parameters = array();
}
public function add(array $parameters)
{
foreach ($parameters as $key => $value) {
$this->parameters[strtolower($key)] = $value;
}
}
public function all()
{
return $this->parameters;
}
public function get($name)
{
$name = strtolower($name);
if (!array_key_exists($name, $this->parameters)) {
throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}
return $this->parameters[$name];
}
public function set($name, $value)
{
$this->parameters[strtolower($name)] = $value;
}
public function has($name)
{
return array_key_exists(strtolower($name), $this->parameters);
}
public function resolve()
{
foreach ($this->parameters as $key => $value) {
$this->parameters[$key] = $this->resolveValue($value);
}
}
public function resolveValue($value)
{
if (is_array($value)) {
$args = array();
foreach ($value as $k => $v) {
$args[$this->resolveValue($k)] = $this->resolveValue($v);
}
return $args;
}
if (!is_string($value)) {
return $value;
}
if (preg_match('/^%([^%]+)%$/', $value, $match)) {
return $this->get(strtolower($match[1]));
}
return str_replace('%%', '%', preg_replace_callback(array('/(?<!%)%([^%]+)%/'), array($this, 'resolveValueCallback'), $value));
}
protected function resolveValueCallback($match)
{
return $this->get(strtolower($match[1]));
}
}
}
namespace Symfony\Component\DependencyInjection\ParameterBag
{
class FrozenParameterBag extends ParameterBag
{
public function __construct(array $parameters = array())
{
$this->parameters = $parameters;
}
public function clear()
{
throw new \LogicException('Impossible to call clear() on a frozen ParameterBag.');
}
public function add(array $parameters)
{
throw new \LogicException('Impossible to call add() on a frozen ParameterBag.');
}
public function set($name, $value)
{
throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
}
}
}
namespace Symfony\Component\HttpKernel\Bundle
{
interface BundleInterface

View File

@ -4,7 +4,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* ProjectServiceContainer
@ -19,7 +19,16 @@ class ProjectServiceContainer extends Container
*/
public function __construct()
{
parent::__construct(new FrozenParameterBag($this->getDefaultParameters()));
$this->parameters = $this->getDefaultParameters();
$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->set('service_container', $this);
$this->scopes = array();
$this->scopeChildren = array();
}
/**
@ -39,6 +48,35 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* {@inheritdoc}
*/
public function getParameter($name)
{
$name = strtolower($name);
if (!array_key_exists($name, $this->parameters)) {
throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}
return $this->parameters[$name];
}
/**
* {@inheritdoc}
*/
public function hasParameter($name)
{
return array_key_exists(strtolower($name), $this->parameters);
}
/**
* {@inheritdoc}
*/
public function setParameter($name, $value)
{
throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
}
/**
* Gets the default parameters.
*