ProxyManager Bridge
This commit is contained in:
parent
c8f95b5dab
commit
78e3710de8
@ -66,7 +66,8 @@
|
||||
"doctrine/orm": "~2.2,>=2.2.3",
|
||||
"monolog/monolog": "~1.3",
|
||||
"propel/propel1": "1.6.*",
|
||||
"ircmaxell/password-compat": "1.0.*"
|
||||
"ircmaxell/password-compat": "1.0.*",
|
||||
"ocramius/proxy-manager": ">=0.3.1,<0.4-dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\": "src/" },
|
||||
|
4
src/Symfony/Bridge/ProxyManager/.gitignore
vendored
Normal file
4
src/Symfony/Bridge/ProxyManager/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
|
7
src/Symfony/Bridge/ProxyManager/CHANGELOG.md
Normal file
7
src/Symfony/Bridge/ProxyManager/CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* First introduction of `Symfony\Bridge\ProxyManager`
|
19
src/Symfony/Bridge/ProxyManager/LICENSE
Normal file
19
src/Symfony/Bridge/ProxyManager/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2004-2013 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -0,0 +1,62 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\Instantiator;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
|
||||
|
||||
/**
|
||||
* Runtime lazy loading proxy generator
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class RuntimeInstantiator implements InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\Factory\LazyLoadingValueHolderFactory
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$config = new Configuration();
|
||||
|
||||
$config->setGeneratorStrategy(new EvaluatingGeneratorStrategy());
|
||||
|
||||
$this->factory = new LazyLoadingValueHolderFactory($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator)
|
||||
{
|
||||
return $this->factory->createProxy(
|
||||
$definition->getClass(),
|
||||
function (& $wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) {
|
||||
$proxy->setProxyInitializer(null);
|
||||
|
||||
$wrappedInstance = call_user_func($realInstantiator);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\PhpDumper;
|
||||
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
||||
|
||||
/**
|
||||
* Generates dumped php code of proxies via reflection
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class ProxyDumper implements DumperInterface
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator
|
||||
*/
|
||||
private $proxyGenerator;
|
||||
|
||||
/**
|
||||
* @var \ProxyManager\GeneratorStrategy\BaseGeneratorStrategy
|
||||
*/
|
||||
private $classGenerator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->proxyGenerator = new LazyLoadingValueHolderGenerator();
|
||||
$this->classGenerator = new BaseGeneratorStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition)
|
||||
{
|
||||
return $definition->isLazy()
|
||||
&& ($class = $definition->getClass())
|
||||
&& class_exists($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id)
|
||||
{
|
||||
$instantiation = 'return';
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
||||
$instantiation .= " \$this->services['$id'] =";
|
||||
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
$instantiation .= " \$this->services['$id'] = \$this->scopedServices['$scope']['$id'] =";
|
||||
}
|
||||
|
||||
$methodName = 'get' . Container::camelize($id) . 'Service';
|
||||
$proxyClass = $this->getProxyClassName($definition);
|
||||
|
||||
return <<<EOF
|
||||
if (\$lazyLoad) {
|
||||
\$container = \$this;
|
||||
|
||||
$instantiation new $proxyClass(
|
||||
function (& \$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$container) {
|
||||
\$proxy->setProxyInitializer(null);
|
||||
|
||||
\$wrappedInstance = \$container->$methodName(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyCode(Definition $definition)
|
||||
{
|
||||
$generatedClass = new ClassGenerator($this->getProxyClassName($definition));
|
||||
|
||||
$this->proxyGenerator->generate(new \ReflectionClass($definition->getClass()), $generatedClass);
|
||||
|
||||
return $this->classGenerator->generate($generatedClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the proxy class name for the given definition
|
||||
*
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getProxyClassName(Definition $definition)
|
||||
{
|
||||
return str_replace('\\', '', $definition->getClass()) . '_' . spl_object_hash($definition);
|
||||
}
|
||||
}
|
13
src/Symfony/Bridge/ProxyManager/README.md
Normal file
13
src/Symfony/Bridge/ProxyManager/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
ProxyManager Bridge
|
||||
===================
|
||||
|
||||
Provides integration for [ProxyManager](https://github.com/Ocramius/ProxyManager) with various Symfony2 components.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
You can run the unit tests with the following command:
|
||||
|
||||
$ cd path/to/Symfony/Bridge/ProxyManager/
|
||||
$ composer.phar install --dev
|
||||
$ phpunit
|
@ -0,0 +1,56 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\Tests;
|
||||
|
||||
require_once __DIR__ . '/Fixtures/includes/foo.php';
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Integration tests for {@see \Symfony\Component\DependencyInjection\ContainerBuilder} combined
|
||||
* with the ProxyManager bridge
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService
|
||||
*/
|
||||
public function testCreateProxyServiceWithRuntimeInstantiator()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
|
||||
$builder->setProxyInstantiator(new RuntimeInstantiator());
|
||||
|
||||
$builder->register('foo1', 'ProxyManagerBridgeFooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
|
||||
$builder->getDefinition('foo1')->setLazy(true);
|
||||
|
||||
/* @var $foo1 \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$foo1 = $builder->get('foo1');
|
||||
|
||||
$this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls');
|
||||
$this->assertInstanceOf('\ProxyManagerBridgeFooClass', $foo1);
|
||||
$this->assertInstanceOf('\ProxyManager\Proxy\LazyLoadingInterface', $foo1);
|
||||
$this->assertFalse($foo1->isProxyInitialized());
|
||||
|
||||
$foo1->initializeProxy();
|
||||
|
||||
$this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved after initialization');
|
||||
$this->assertTrue($foo1->isProxyInitialized());
|
||||
$this->assertInstanceOf('\ProxyManagerBridgeFooClass', $foo1->getWrappedValueHolderValue());
|
||||
$this->assertNotInstanceOf('\ProxyManager\Proxy\LazyLoadingInterface', $foo1->getWrappedValueHolderValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\Tests\Dumper;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
|
||||
/**
|
||||
* Integration tests for {@see \Symfony\Component\DependencyInjection\Dumper\PhpDumper} combined
|
||||
* with the ProxyManager bridge
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testDumpContainerWithProxyService()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('foo', 'stdClass');
|
||||
$container->getDefinition('foo')->setLazy(true);
|
||||
$container->compile();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$dumper->setProxyDumper(new ProxyDumper());
|
||||
|
||||
$dumpedString = $dumper->dump();
|
||||
|
||||
$this->assertStringMatchesFormatFile(
|
||||
__DIR__ . '/../Fixtures/php/lazy_service_structure.txt',
|
||||
$dumpedString,
|
||||
'->dump() does generate proxy lazy loading logic.'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the generated container retrieves the same proxy instance on multiple subsequent requests
|
||||
*/
|
||||
public function testDumpContainerWithProxyServiceWillShareProxies()
|
||||
{
|
||||
require_once __DIR__ . '/../Fixtures/php/lazy_service.php';
|
||||
|
||||
$container = new \LazyServiceProjectServiceContainer();
|
||||
|
||||
/* @var $proxy \stdClass_c1d194250ee2e2b7d2eab8b8212368a8 */
|
||||
$proxy = $container->get('foo');
|
||||
|
||||
$this->assertInstanceOf('stdClass_c1d194250ee2e2b7d2eab8b8212368a8', $proxy);
|
||||
$this->assertSame($proxy, $container->get('foo'));
|
||||
|
||||
$this->assertFalse($proxy->isProxyInitialized());
|
||||
|
||||
$proxy->initializeProxy();
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($proxy, $container->get('foo'));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class ProxyManagerBridgeFooClass
|
||||
{
|
||||
public $foo, $moo;
|
||||
|
||||
public $bar = null, $initialized = false, $configured = false, $called = false, $arguments = array();
|
||||
|
||||
public function __construct($arguments = array())
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public static function getInstance($arguments = array())
|
||||
{
|
||||
$obj = new self($arguments);
|
||||
$obj->called = true;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
$this->initialized = true;
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->configured = true;
|
||||
}
|
||||
|
||||
public function setBar($value = null)
|
||||
{
|
||||
$this->bar = $value;
|
||||
}
|
||||
}
|
@ -0,0 +1,199 @@
|
||||
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
|
||||
/**
|
||||
* ProjectServiceContainer
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Dependency Injection Component.
|
||||
*/
|
||||
class LazyServiceProjectServiceContainer extends Container
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->services =
|
||||
$this->scopedServices =
|
||||
$this->scopeStacks = array();
|
||||
|
||||
$this->set('service_container', $this);
|
||||
|
||||
$this->scopes = array();
|
||||
$this->scopeChildren = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'foo' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @param boolean $lazyLoad whether to try lazy-loading the service with a proxy
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
public function getFooService($lazyLoad = true)
|
||||
{
|
||||
if ($lazyLoad) {
|
||||
$container = $this;
|
||||
|
||||
return $this->services['foo'] = new stdClass_c1d194250ee2e2b7d2eab8b8212368a8(
|
||||
function (& $wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
|
||||
$proxy->setProxyInitializer(null);
|
||||
|
||||
$wrappedInstance = $container->getFooService(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
class stdClass_c1d194250ee2e2b7d2eab8b8212368a8 extends \stdClass implements \ProxyManager\Proxy\LazyLoadingInterface, \ProxyManager\Proxy\ValueHolderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Closure|null initializer responsible for generating the wrapped object
|
||||
*/
|
||||
private $valueHolder5157dd96e88c0 = null;
|
||||
|
||||
/**
|
||||
* @var \Closure|null initializer responsible for generating the wrapped object
|
||||
*/
|
||||
private $initializer5157dd96e8924 = null;
|
||||
|
||||
/**
|
||||
* @override constructor for lazy initialization
|
||||
*
|
||||
* @param \Closure|null $initializer
|
||||
*/
|
||||
public function __construct($initializer)
|
||||
{
|
||||
$this->initializer5157dd96e8924 = $initializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__get', array('name' => $name));
|
||||
|
||||
return $this->valueHolder5157dd96e88c0->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__set', array('name' => $name, 'value' => $value));
|
||||
|
||||
$this->valueHolder5157dd96e88c0->$name = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__isset', array('name' => $name));
|
||||
|
||||
return isset($this->valueHolder5157dd96e88c0->$name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__unset', array('name' => $name));
|
||||
|
||||
unset($this->valueHolder5157dd96e88c0->$name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__clone', array());
|
||||
|
||||
$this->valueHolder5157dd96e88c0 = clone $this->valueHolder5157dd96e88c0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__sleep', array());
|
||||
|
||||
return array('valueHolder5157dd96e88c0');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setProxyInitializer(\Closure $initializer = null)
|
||||
{
|
||||
$this->initializer5157dd96e8924 = $initializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyInitializer()
|
||||
{
|
||||
return $this->initializer5157dd96e8924;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initializeProxy()
|
||||
{
|
||||
return $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, 'initializeProxy', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isProxyInitialized()
|
||||
{
|
||||
return null !== $this->valueHolder5157dd96e88c0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getWrappedValueHolderValue()
|
||||
{
|
||||
return $this->valueHolder5157dd96e88c0;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use %a
|
||||
class ProjectServiceContainer extends Container
|
||||
{%a
|
||||
public function getFooService($lazyLoad = true)
|
||||
{
|
||||
if ($lazyLoad) {
|
||||
$container = $this;
|
||||
|
||||
return $this->services['foo'] = new stdClass_%s(
|
||||
function (& $wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
|
||||
$proxy->setProxyInitializer(null);
|
||||
|
||||
$wrappedInstance = $container->getFooService(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
class stdClass_%s extends \stdClass implements \ProxyManager\Proxy\LazyLoadingInterface, \ProxyManager\Proxy\ValueHolderInterface
|
||||
{%a}%A
|
@ -0,0 +1,62 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\Tests\Instantiator;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator}
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @covers \Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator
|
||||
*/
|
||||
class RuntimeInstantiatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var RuntimeInstantiator
|
||||
*/
|
||||
protected $instantiator;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->instantiator = new RuntimeInstantiator();
|
||||
}
|
||||
|
||||
public function testInstantiateProxy()
|
||||
{
|
||||
$instance = new \stdClass();
|
||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
||||
$definition = new Definition('stdClass');
|
||||
$instantiator = function () use ($instance) {
|
||||
return $instance;
|
||||
};
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$proxy = $this->instantiator->instantiateProxy($container, $definition, 'foo', $instantiator);
|
||||
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\LazyLoadingInterface', $proxy);
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\ValueHolderInterface', $proxy);
|
||||
$this->assertFalse($proxy->isProxyInitialized());
|
||||
|
||||
$proxy->initializeProxy();
|
||||
|
||||
$this->assertSame($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
<?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\Bridge\ProxyManager\LazyProxy\Tests\Instantiator;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper}
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @covers \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper
|
||||
*/
|
||||
class ProxyDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var ProxyDumper
|
||||
*/
|
||||
protected $dumper;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->dumper = new ProxyDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyCandidates
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param bool $expected
|
||||
*/
|
||||
public function testIsProxyCandidate(Definition $definition, $expected)
|
||||
{
|
||||
$this->assertSame($expected, $this->dumper->isProxyCandidate($definition));
|
||||
}
|
||||
|
||||
public function testGetProxyCode()
|
||||
{
|
||||
$definition = new Definition(__CLASS__);
|
||||
|
||||
$definition->setLazy(true);
|
||||
|
||||
$code = $this->dumper->getProxyCode($definition);
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
'%Aclass SymfonyBridgeProxyManagerLazyProxyTestsInstantiatorProxyDumperTest%aextends%w'
|
||||
. '\Symfony\Bridge\ProxyManager\LazyProxy\Tests\Instantiator%a',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetProxyFactoryCode()
|
||||
{
|
||||
$definition = new Definition(__CLASS__);
|
||||
|
||||
$definition->setLazy(true);
|
||||
|
||||
$code = $this->dumper->getProxyFactoryCode($definition, 'foo');
|
||||
|
||||
$this->assertStringMatchesFormat(
|
||||
'%wif ($lazyLoad) {%w$container = $this;%wreturn $this->services[\'foo\'] = new '
|
||||
. 'SymfonyBridgeProxyManagerLazyProxyTestsInstantiatorProxyDumperTest_%s(%wfunction '
|
||||
. '(& $wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {'
|
||||
. '%w$proxy->setProxyInitializer(null);%w$wrappedInstance = $container->getFooService(false);'
|
||||
. '%wreturn true;%w}%w);%w}%w',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyCandidates()
|
||||
{
|
||||
$definitions = array(
|
||||
array(new Definition(__CLASS__), true),
|
||||
array(new Definition('stdClass'), true),
|
||||
array(new Definition('foo' . uniqid()), false),
|
||||
array(new Definition(), false),
|
||||
);
|
||||
|
||||
array_map(
|
||||
function ($definition) {
|
||||
$definition[0]->setLazy(true);
|
||||
},
|
||||
$definitions
|
||||
);
|
||||
|
||||
return $definitions;
|
||||
}
|
||||
}
|
35
src/Symfony/Bridge/ProxyManager/composer.json
Normal file
35
src/Symfony/Bridge/ProxyManager/composer.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "symfony/proxy-manager-bridge",
|
||||
"type": "symfony-bridge",
|
||||
"description": "Symfony ProxyManager Bridge",
|
||||
"keywords": [],
|
||||
"homepage": "http://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/dependency-injection": ">=2.3-dev,<2.4-dev",
|
||||
"ocramius/proxy-manager": ">=0.3.1,<0.4-dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bridge\\ProxyManager\\": ""
|
||||
}
|
||||
},
|
||||
"target-dir": "Symfony/Bridge/ProxyManager",
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
}
|
||||
}
|
31
src/Symfony/Bridge/ProxyManager/phpunit.xml.dist
Normal file
31
src/Symfony/Bridge/ProxyManager/phpunit.xml.dist
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Symfony ProxyManager Bridge Test Suite">
|
||||
<directory>./Tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./Resources</directory>
|
||||
<directory>./Tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
@ -22,6 +22,8 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
|
||||
|
||||
/**
|
||||
* ContainerBuilder is a DI container that provides an API to easily describe services.
|
||||
@ -71,6 +73,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
|
||||
private $trackResources = true;
|
||||
|
||||
/**
|
||||
* @var InstantiatorInterface|null
|
||||
*/
|
||||
private $proxyInstantiator;
|
||||
|
||||
/**
|
||||
* Sets the track resources flag.
|
||||
*
|
||||
@ -94,6 +101,16 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
return $this->trackResources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instantiator to be used when fetching proxies.
|
||||
*
|
||||
* @param InstantiatorInterface $proxyInstantiator
|
||||
*/
|
||||
public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator)
|
||||
{
|
||||
$this->proxyInstantiator = $proxyInstantiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an extension.
|
||||
*
|
||||
@ -222,15 +239,30 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
* @api
|
||||
*/
|
||||
public function addObjectResource($object)
|
||||
{
|
||||
if ($this->trackResources) {
|
||||
$this->addClassResource(new \ReflectionClass($object));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given class hierarchy as resources.
|
||||
*
|
||||
* @param \ReflectionClass $class
|
||||
*
|
||||
* @return ContainerBuilder The current instance
|
||||
*/
|
||||
public function addClassResource(\ReflectionClass $class)
|
||||
{
|
||||
if (!$this->trackResources) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$parent = new \ReflectionObject($object);
|
||||
do {
|
||||
$this->addResource(new FileResource($parent->getFileName()));
|
||||
} while ($parent = $parent->getParentClass());
|
||||
$this->addResource(new FileResource($class->getFileName()));
|
||||
} while ($class = $class->getParentClass());
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -417,8 +449,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
*
|
||||
* @return object The associated service
|
||||
*
|
||||
* @throws InvalidArgumentException if the service is not defined
|
||||
* @throws LogicException if the service has a circular reference to itself
|
||||
* @throws InvalidArgumentException when no definitions are available
|
||||
* @throws InactiveScopeException when the current scope is not active
|
||||
* @throws LogicException when a circular dependency is detected
|
||||
* @throws \Exception
|
||||
*
|
||||
* @see Reference
|
||||
*
|
||||
@ -584,6 +618,12 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
foreach ($this->compiler->getPassConfig()->getPasses() as $pass) {
|
||||
$this->addObjectResource($pass);
|
||||
}
|
||||
|
||||
foreach ($this->definitions as $definition) {
|
||||
if ($definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) {
|
||||
$this->addClassResource(new \ReflectionClass($class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->compiler->compile($this);
|
||||
@ -865,6 +905,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
*
|
||||
* @param Definition $definition A service definition instance
|
||||
* @param string $id The service identifier
|
||||
* @param Boolean $tryProxy Whether to try proxying the service with a lazy proxy
|
||||
*
|
||||
* @return object The service described by the service definition
|
||||
*
|
||||
@ -872,13 +913,32 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
* @throws RuntimeException When the factory definition is incomplete
|
||||
* @throws RuntimeException When the service is a synthetic service
|
||||
* @throws InvalidArgumentException When configure callable is not callable
|
||||
*
|
||||
* @internal this method is public because of PHP 5.3 limitations, do not use it explicitly in your code
|
||||
*/
|
||||
private function createService(Definition $definition, $id)
|
||||
public function createService(Definition $definition, $id, $tryProxy = true)
|
||||
{
|
||||
if ($definition->isSynthetic()) {
|
||||
throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
|
||||
}
|
||||
|
||||
if ($tryProxy && $definition->isLazy()) {
|
||||
$container = $this;
|
||||
|
||||
$proxy = $this
|
||||
->getProxyInstantiator()
|
||||
->instantiateProxy(
|
||||
$container,
|
||||
$definition,
|
||||
$id, function () use ($definition, $id, $container) {
|
||||
return $container->createService($definition, $id, false);
|
||||
}
|
||||
);
|
||||
$this->shareService($definition, $proxy, $id);
|
||||
|
||||
return $proxy;
|
||||
}
|
||||
|
||||
$parameterBag = $this->getParameterBag();
|
||||
|
||||
if (null !== $definition->getFile()) {
|
||||
@ -903,16 +963,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
|
||||
}
|
||||
|
||||
if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
|
||||
throw new InactiveScopeException($id, $scope);
|
||||
}
|
||||
|
||||
$this->services[$lowerId = strtolower($id)] = $service;
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
$this->scopedServices[$scope][$lowerId] = $service;
|
||||
}
|
||||
if ($tryProxy || !$definition->isLazy()) {
|
||||
// share only if proxying failed, or if not a proxy
|
||||
$this->shareService($definition, $service, $id);
|
||||
}
|
||||
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
@ -1019,6 +1072,20 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the currently set proxy instantiator or instantiates one.
|
||||
*
|
||||
* @return InstantiatorInterface
|
||||
*/
|
||||
private function getProxyInstantiator()
|
||||
{
|
||||
if (!$this->proxyInstantiator) {
|
||||
$this->proxyInstantiator = new RealServiceInstantiator();
|
||||
}
|
||||
|
||||
return $this->proxyInstantiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes a service change.
|
||||
*
|
||||
@ -1057,4 +1124,28 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
|
||||
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares a given service in the container
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param mixed $service
|
||||
* @param string $id
|
||||
*
|
||||
* @throws InactiveScopeException
|
||||
*/
|
||||
private function shareService(Definition $definition, $service, $id)
|
||||
{
|
||||
if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
|
||||
throw new InactiveScopeException($id, $scope);
|
||||
}
|
||||
|
||||
$this->services[$lowerId = strtolower($id)] = $service;
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
$this->scopedServices[$scope][$lowerId] = $service;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class Definition
|
||||
private $synthetic;
|
||||
private $abstract;
|
||||
private $synchronized;
|
||||
private $lazy;
|
||||
|
||||
protected $arguments;
|
||||
|
||||
@ -58,6 +59,7 @@ class Definition
|
||||
$this->public = true;
|
||||
$this->synthetic = false;
|
||||
$this->synchronized = false;
|
||||
$this->lazy = false;
|
||||
$this->abstract = false;
|
||||
$this->properties = array();
|
||||
}
|
||||
@ -599,6 +601,30 @@ class Definition
|
||||
return $this->synchronized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lazy flag of this service.
|
||||
*
|
||||
* @param Boolean $lazy
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*/
|
||||
public function setLazy($lazy)
|
||||
{
|
||||
$this->lazy = (Boolean) $lazy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this service is lazy.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isLazy()
|
||||
{
|
||||
return $this->lazy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this definition is synthetic, that is not constructed by the
|
||||
* container, but dynamically injected.
|
||||
|
@ -21,6 +21,8 @@ use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
|
||||
|
||||
/**
|
||||
* PhpDumper dumps a service container as a PHP class.
|
||||
@ -50,6 +52,11 @@ class PhpDumper extends Dumper
|
||||
private $variableCount;
|
||||
private $reservedVariables = array('instance', 'class');
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface
|
||||
*/
|
||||
private $proxyDumper;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@ -62,6 +69,16 @@ class PhpDumper extends Dumper
|
||||
$this->inlinedDefinitions = new \SplObjectStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dumper to be used when dumping proxies in the generated container.
|
||||
*
|
||||
* @param ProxyDumper $proxyDumper
|
||||
*/
|
||||
public function setProxyDumper(ProxyDumper $proxyDumper)
|
||||
{
|
||||
$this->proxyDumper = $proxyDumper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the service container as a PHP class.
|
||||
*
|
||||
@ -94,12 +111,27 @@ class PhpDumper extends Dumper
|
||||
$code .=
|
||||
$this->addServices().
|
||||
$this->addDefaultParametersMethod().
|
||||
$this->endClass()
|
||||
$this->endClass().
|
||||
$this->addProxyClasses()
|
||||
;
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the currently set proxy dumper or instantiates one.
|
||||
*
|
||||
* @return ProxyDumper
|
||||
*/
|
||||
private function getProxyDumper()
|
||||
{
|
||||
if (!$this->proxyDumper) {
|
||||
$this->proxyDumper = new NullDumper();
|
||||
}
|
||||
|
||||
return $this->proxyDumper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates Service local temp variables.
|
||||
*
|
||||
@ -149,6 +181,27 @@ class PhpDumper extends Dumper
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code for the proxies to be attached after the container class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addProxyClasses()
|
||||
{
|
||||
/* @var $proxyDefinitions Definition[] */
|
||||
$definitions = array_filter(
|
||||
$this->container->getDefinitions(),
|
||||
array($this->getProxyDumper(), 'isProxyCandidate')
|
||||
);
|
||||
$code = '';
|
||||
|
||||
foreach ($definitions as $definition) {
|
||||
$code .= "\n" . $this->getProxyDumper()->getProxyCode($definition);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the require_once statement for service includes.
|
||||
*
|
||||
@ -281,11 +334,12 @@ class PhpDumper extends Dumper
|
||||
}
|
||||
|
||||
$simple = $this->isSimpleInstance($id, $definition);
|
||||
|
||||
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
|
||||
$instantiation = '';
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
||||
|
||||
if (!$isProxyCandidate && ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
||||
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
|
||||
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
} elseif (!$isProxyCandidate && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
|
||||
} elseif (!$simple) {
|
||||
$instantiation = '$instance';
|
||||
@ -483,18 +537,32 @@ EOF;
|
||||
EOF;
|
||||
}
|
||||
|
||||
if ($definition->isLazy()) {
|
||||
$lazyInitialization = '$lazyLoad = true';
|
||||
$lazyInitializationDoc = "\n * @param boolean \$lazyLoad whether to try lazy-loading the"
|
||||
. " service with a proxy\n *";
|
||||
} else {
|
||||
$lazyInitialization = '';
|
||||
$lazyInitializationDoc = '';
|
||||
}
|
||||
|
||||
// with proxies, for 5.3.3 compatibility, the getter must be public to be accessible to the initializer
|
||||
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
|
||||
$visibility = $isProxyCandidate ? 'public' : 'protected';
|
||||
$code = <<<EOF
|
||||
|
||||
/**
|
||||
* Gets the '$id' service.$doc
|
||||
*
|
||||
*$lazyInitializationDoc
|
||||
* $return
|
||||
*/
|
||||
protected function get{$name}Service()
|
||||
{$visibility} function get{$name}Service($lazyInitialization)
|
||||
{
|
||||
|
||||
EOF;
|
||||
|
||||
$code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id) : '';
|
||||
|
||||
if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
|
||||
$code .= <<<EOF
|
||||
if (!isset(\$this->scopedServices['$scope'])) {
|
||||
|
@ -133,6 +133,9 @@ class XmlDumper extends Dumper
|
||||
if ($definition->isSynchronized()) {
|
||||
$service->setAttribute('synchronized', 'true');
|
||||
}
|
||||
if ($definition->isLazy()) {
|
||||
$service->setAttribute('lazy', 'true');
|
||||
}
|
||||
|
||||
foreach ($definition->getTags() as $name => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
|
@ -106,6 +106,10 @@ class YamlDumper extends Dumper
|
||||
$code .= sprintf(" factory_class: %s\n", $definition->getFactoryClass());
|
||||
}
|
||||
|
||||
if ($definition->isLazy()) {
|
||||
$code .= sprintf(" lazy: true\n");
|
||||
}
|
||||
|
||||
if ($definition->getFactoryMethod()) {
|
||||
$code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod());
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?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\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Lazy proxy instantiator, capable of instantiating a proxy given a container, the
|
||||
* service definitions and a callback that produces the real service instance.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
interface InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container the container from which the service is being requested
|
||||
* @param Definition $definition the definitions of the requested service
|
||||
* @param string $id identifier of the requested service
|
||||
* @param callable $realInstantiator zero-argument callback that is capable of producing the real
|
||||
* service instance
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?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\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Noop proxy instantiator - simply produces the real service instead of a proxy instance.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class RealServiceInstantiator implements InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator)
|
||||
{
|
||||
return call_user_func($realInstantiator);
|
||||
}
|
||||
}
|
@ -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\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Lazy proxy dumper capable of generating the instantiation logic php code for proxied services.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Inspects whether the given definitions should produce proxy instantiation logic in the dumped container.
|
||||
*
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition);
|
||||
|
||||
/**
|
||||
* Generates the code to be used to instantiate a proxy in the dumped factory code.
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param string $id service identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id);
|
||||
|
||||
/**
|
||||
* Generates the code for the lazy proxy.
|
||||
*
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyCode(Definition $definition);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?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\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Null dumper, negates any proxy code generation for any given service definition.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class NullDumper implements DumperInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyCode(Definition $definition)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
@ -148,7 +148,7 @@ class XmlFileLoader extends FileLoader
|
||||
$definition = new Definition();
|
||||
}
|
||||
|
||||
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'synchronized', 'abstract') as $key) {
|
||||
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'synchronized', 'lazy', 'abstract') as $key) {
|
||||
if (isset($service[$key])) {
|
||||
$method = 'set'.str_replace('-', '', $key);
|
||||
$definition->$method((string) $service->getAttributeAsPhp($key));
|
||||
|
@ -157,6 +157,10 @@ class YamlFileLoader extends FileLoader
|
||||
$definition->setSynchronized($service['synchronized']);
|
||||
}
|
||||
|
||||
if (isset($service['lazy'])) {
|
||||
$definition->setLazy($service['lazy']);
|
||||
}
|
||||
|
||||
if (isset($service['public'])) {
|
||||
$definition->setPublic($service['public']);
|
||||
}
|
||||
|
@ -87,6 +87,7 @@
|
||||
<xsd:attribute name="public" type="boolean" />
|
||||
<xsd:attribute name="synthetic" type="boolean" />
|
||||
<xsd:attribute name="synchronized" type="boolean" />
|
||||
<xsd:attribute name="lazy" type="boolean" />
|
||||
<xsd:attribute name="abstract" type="boolean" />
|
||||
<xsd:attribute name="factory-class" type="xsd:string" />
|
||||
<xsd:attribute name="factory-method" type="xsd:string" />
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Tests;
|
||||
require_once __DIR__.'/Fixtures/includes/classes.php';
|
||||
require_once __DIR__.'/Fixtures/includes/ProjectExtension.php';
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -263,6 +264,22 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertInstanceOf('\FooClass', $builder->get('foo2'), '->createService() replaces parameters in the file provided by the service definition');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService
|
||||
*/
|
||||
public function testCreateProxyWithRealServiceInstantiator()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
|
||||
$builder->register('foo1', 'FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
|
||||
$builder->getDefinition('foo1')->setLazy(true);
|
||||
|
||||
$foo1 = $builder->get('foo1');
|
||||
|
||||
$this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls');
|
||||
$this->assertSame('FooClass', get_class($foo1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::createService
|
||||
*/
|
||||
@ -465,6 +482,95 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals($definition, $container->findDefinition('foobar'), '->findDefinition() returns a Definition');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::addObjectResource
|
||||
*/
|
||||
public function testAddObjectResource()
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$this->markTestSkipped('The "Config" component is not available');
|
||||
}
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->setResourceTracking(false);
|
||||
$container->addObjectResource(new \BarClass());
|
||||
|
||||
$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');
|
||||
|
||||
$container->setResourceTracking(true);
|
||||
$container->addObjectResource(new \BarClass());
|
||||
|
||||
$resources = $container->getResources();
|
||||
|
||||
$this->assertCount(1, $resources, '1 resource was registered');
|
||||
|
||||
/* @var $resource \Symfony\Component\Config\Resource\FileResource */
|
||||
$resource = end($resources);
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
|
||||
$this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::addClassResource
|
||||
*/
|
||||
public function testAddClassResource()
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$this->markTestSkipped('The "Config" component is not available');
|
||||
}
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->setResourceTracking(false);
|
||||
$container->addClassResource(new \ReflectionClass('BarClass'));
|
||||
|
||||
$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');
|
||||
|
||||
$container->setResourceTracking(true);
|
||||
$container->addClassResource(new \ReflectionClass('BarClass'));
|
||||
|
||||
$resources = $container->getResources();
|
||||
|
||||
$this->assertCount(1, $resources, '1 resource was registered');
|
||||
|
||||
/* @var $resource \Symfony\Component\Config\Resource\FileResource */
|
||||
$resource = end($resources);
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
|
||||
$this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::compile
|
||||
*/
|
||||
public function testCompilesClassDefinitionsOfLazyServices()
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
|
||||
$this->markTestSkipped('The "Config" component is not available');
|
||||
}
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');
|
||||
|
||||
$container->register('foo', 'BarClass');
|
||||
$container->getDefinition('foo')->setLazy(true);
|
||||
|
||||
$container->compile();
|
||||
|
||||
$classesPath = realpath(__DIR__.'/Fixtures/includes/classes.php');
|
||||
$matchingResources = array_filter(
|
||||
$container->getResources(),
|
||||
function (ResourceInterface $resource) use ($classesPath) {
|
||||
return $resource instanceof FileResource && $classesPath === realpath($resource->getResource());
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertNotEmpty($matchingResources);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::getResources
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::addResource
|
||||
|
@ -164,6 +164,18 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($def->isSynchronized(), '->isSynchronized() returns true if the service is synchronized.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::setLazy
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::isLazy
|
||||
*/
|
||||
public function testSetIsLazy()
|
||||
{
|
||||
$def = new Definition('stdClass');
|
||||
$this->assertFalse($def->isLazy(), '->isLazy() returns false by default');
|
||||
$this->assertSame($def, $def->setLazy(true), '->setLazy() implements a fluent interface');
|
||||
$this->assertTrue($def->isLazy(), '->isLazy() returns true if the service is lazy.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::setAbstract
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::isAbstract
|
||||
|
@ -46,6 +46,6 @@
|
||||
<service id="alias_for_foo" alias="foo" />
|
||||
<service id="another_alias_for_foo" alias="foo" public="false" />
|
||||
<service id="factory_service" factory-method="getInstance" factory-service="baz_factory" />
|
||||
<service id="request" class="Request" synthetic="true" synchronized="true"/>
|
||||
<service id="request" class="Request" synthetic="true" synchronized="true" lazy="true"/>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -28,3 +28,4 @@ services:
|
||||
class: Request
|
||||
synthetic: true
|
||||
synchronized: true
|
||||
lazy: true
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?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\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Symfony\Component\DependencyInjection\Instantiator\RealServiceInstantiator}
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @covers \Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator
|
||||
*/
|
||||
class RealServiceInstantiatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInstantiateProxy()
|
||||
{
|
||||
$instantiator = new RealServiceInstantiator();
|
||||
$instance = new \stdClass();
|
||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
||||
$callback = function () use ($instance) {
|
||||
return $instance;
|
||||
};
|
||||
|
||||
$this->assertSame($instance, $instantiator->instantiateProxy($container, new Definition(), 'foo', $callback));
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?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\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Symfony\Component\DependencyInjection\PhpDumper\NullDumper}
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @covers \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper
|
||||
*/
|
||||
class NullDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testNullDumper()
|
||||
{
|
||||
$dumper = new NullDumper();
|
||||
$definition = new Definition('stdClass');
|
||||
|
||||
$this->assertFalse($dumper->isProxyCandidate($definition));
|
||||
$this->assertSame('', $dumper->getProxyFactoryCode($definition, 'foo'));
|
||||
$this->assertSame('', $dumper->getProxyCode($definition));
|
||||
}
|
||||
}
|
@ -187,6 +187,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
|
||||
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
|
||||
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
|
||||
|
||||
$aliases = $container->getAliases();
|
||||
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses <service> elements');
|
||||
|
@ -130,6 +130,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
|
||||
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
|
||||
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
|
||||
|
||||
$aliases = $container->getAliases();
|
||||
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases');
|
||||
|
@ -24,7 +24,8 @@
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "2.2.*",
|
||||
"symfony/config": "2.2.*"
|
||||
"symfony/config": "2.2.*",
|
||||
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\Component\\DependencyInjection\\": "" }
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
@ -684,7 +686,13 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
*/
|
||||
protected function getContainerBuilder()
|
||||
{
|
||||
return new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
|
||||
$container = new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
|
||||
|
||||
if (class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) {
|
||||
$container->setProxyInstantiator(new RuntimeInstantiator());
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -699,6 +707,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
{
|
||||
// cache the container
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
if (class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) {
|
||||
$dumper->setProxyDumper(new ProxyDumper());
|
||||
}
|
||||
|
||||
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass));
|
||||
if (!$this->debug) {
|
||||
$content = self::stripComments($content);
|
||||
|
Reference in New Issue
Block a user