Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
Anthony MARTIN committed Feb 7, 2019
1 parent 32e1400 commit df8dd1d
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 2 deletions.
Expand Up @@ -687,7 +687,7 @@ protected function {$methodName}($lazyInitialization)
$code .= $this->addServiceInclude($id, $definition);

if ($this->getProxyDumper()->isProxyCandidate($definition)) {
$factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)';
$factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : "\$this->factories['%s'](false)") : '$this->%s(false)';
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName));
}

Expand Down Expand Up @@ -862,7 +862,9 @@ private function generateServiceFiles(array $services)
}
$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];
}

Expand Down
Expand Up @@ -230,6 +230,24 @@ public function testDumpAsFiles()
$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';
Expand Down
@@ -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');

)

0 comments on commit df8dd1d

Please sign in to comment.