[DependencyInjection] fix #29930 add $lazyLoad flag to the generated factory code for lazy non-shared services
| Q | A | ------------- | --- | Branch? | 4.1 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #29930 | License | MIT | Doc PR | n/a Fix #29930 by adding $lazyLoad context to the generated code for lazy non-shared service by PhpDumper
This commit is contained in:
parent
32e14005a6
commit
98d4dfdadb
@ -687,8 +687,8 @@ EOF;
|
||||
$code .= $this->addServiceInclude($id, $definition);
|
||||
|
||||
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
|
||||
$factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)';
|
||||
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName));
|
||||
$factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : "\$this->factories['%2$s'](false)") : '$this->%s(false)';
|
||||
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->export($id)));
|
||||
}
|
||||
|
||||
if ($definition->isDeprecated()) {
|
||||
@ -862,7 +862,9 @@ EOTXT
|
||||
}
|
||||
$code[1] = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code[1])));
|
||||
$factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id);
|
||||
$code[1] = sprintf("%s = function () {\n%s};\n\nreturn %1\$s();\n", $factory, $code[1]);
|
||||
$lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';
|
||||
|
||||
$code[1] = sprintf("%s = function (%s) {\n%s};\n\nreturn %1\$s();\n", $factory, $lazyloadInitialization, $code[1]);
|
||||
$code = $code[0].$code[1];
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,24 @@ class PhpDumperTest extends TestCase
|
||||
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
|
||||
}
|
||||
|
||||
public function testNonSharedLazyDumpAsFiles()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container_non_shared_lazy.php';
|
||||
$container->register('non_shared_foo', \Bar\FooLazyClass::class)
|
||||
->setFile(realpath(self::$fixturesPath.'/includes/foo_lazy.php'))
|
||||
->setShared(false)
|
||||
->setPublic(true)
|
||||
->setLazy(true);
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__]), true);
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$dump = str_replace('\\\\Fixtures\\\\includes\\\\foo_lazy.php', '/Fixtures/includes/foo_lazy.php', $dump);
|
||||
}
|
||||
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services_non_shared_lazy_as_files.txt', $dump);
|
||||
}
|
||||
|
||||
public function testServicesWithAnonymousFactories()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container19.php';
|
||||
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
return new ContainerBuilder();
|
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Bar;
|
||||
|
||||
class FooLazyClass
|
||||
{
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
Array
|
||||
(
|
||||
[Container%s/removed-ids.php] => <?php
|
||||
|
||||
return [
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||
];
|
||||
|
||||
[Container%s/getNonSharedFooService.php] => <?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
|
||||
// Returns the public 'non_shared_foo' service.
|
||||
|
||||
include_once ($this->targetDirs[0].'/Fixtures/includes/foo_lazy.php');
|
||||
|
||||
$this->factories['non_shared_foo'] = function ($lazyLoad = true) {
|
||||
return new \Bar\FooLazyClass();
|
||||
};
|
||||
|
||||
return $this->factories['non_shared_foo']();
|
||||
|
||||
[Container%s/ProjectServiceContainer.php] => <?php
|
||||
|
||||
namespace Container%s;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
|
||||
/**
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Dependency Injection Component.
|
||||
*
|
||||
* @final since Symfony 3.3
|
||||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private $buildParameters;
|
||||
private $containerDir;
|
||||
private $parameters;
|
||||
private $targetDirs = [];
|
||||
|
||||
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
|
||||
{
|
||||
$dir = $this->targetDirs[0] = \dirname($containerDir);
|
||||
for ($i = 1; $i <= 5; ++$i) {
|
||||
$this->targetDirs[$i] = $dir = \dirname($dir);
|
||||
}
|
||||
$this->buildParameters = $buildParameters;
|
||||
$this->containerDir = $containerDir;
|
||||
$this->services = $this->privates = [];
|
||||
$this->fileMap = [
|
||||
'non_shared_foo' => 'getNonSharedFooService.php',
|
||||
];
|
||||
|
||||
$this->aliases = [];
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRemovedIds()
|
||||
{
|
||||
return require $this->containerDir.\DIRECTORY_SEPARATOR.'removed-ids.php';
|
||||
}
|
||||
|
||||
protected function load($file, $lazyLoad = true)
|
||||
{
|
||||
return require $this->containerDir.\DIRECTORY_SEPARATOR.$file;
|
||||
}
|
||||
}
|
||||
|
||||
[ProjectServiceContainer.php] => <?php
|
||||
|
||||
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
|
||||
|
||||
if (\class_exists(\Container%s\ProjectServiceContainer::class, false)) {
|
||||
// no-op
|
||||
} elseif (!include __DIR__.'/Container%s/ProjectServiceContainer.php') {
|
||||
touch(__DIR__.'/Container%s.legacy');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\class_exists(ProjectServiceContainer::class, false)) {
|
||||
\class_alias(\Container%s\ProjectServiceContainer::class, ProjectServiceContainer::class, false);
|
||||
}
|
||||
|
||||
return new \Container%s\ProjectServiceContainer([
|
||||
'container.build_hash' => '%s',
|
||||
'container.build_id' => '%s',
|
||||
'container.build_time' => %d,
|
||||
], __DIR__.\DIRECTORY_SEPARATOR.'Container%s');
|
||||
|
||||
)
|
Reference in New Issue
Block a user