-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Symfony version(s) affected: 4.2 and 4.1
Description
When a service is declared as non-shared, the generated compiled factory wraps its the initialization in a closure. The problem is that the new function doesn't get access to the $lazyLoad parameter which leads to errors if the generated lazy loading code (for example symfony/proxy-manager-bridge) needs to use it.
How to reproduce
<?php
class MyClass {};
$container = new ContainerBuilder();
$container->register('non_shared_foo', \MyClass::class)->setShared(false)->setLazy(true)->setPublic(true);
$container->compile();
$dumper = new PhpDumper($container);
print_r($dumper->dump(['as_files' => true));
The generated getNonSharedFooService.php looks like this:
<?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.
$this->factories['non_shared_foo'] = function () {
// Returns the public 'non_shared_foo' service.
return new \MyClass();
};
return $this->factories['non_shared_foo']();
This would preclude any implementation of a lazy proxy dumper to check whether the service should be lazy or not. For example if the symfony/proxy-manager-bridge is used:
<?php
$container = new ContainerBuilder();
$container->register('non_shared_foo', \MyClass::class)->setShared(false)->setLazy(true)->setPublic(true);
$container->compile();
$dumper = new PhpDumper($container);
$dumper->setProxyDumper(new \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper());
print_r($dumper->dump(['as_files' => true]));
the generated getNonSharedFooService.php would look something like this:
<?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.
$this->factories['non_shared_foo'] = function () {
// Returns the public 'non_shared_foo' service.
if ($lazyLoad) {
return $this->createProxy('MyClass_c5258b3', function () {
return \MyClass_c5258b3::staticProxyConstructor(function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) {
$wrappedInstance = $this->load('getNonSharedFooService.php', false);
$proxy->setProxyInitializer(null);
return true;
});
});
}
return new \MyClass();
};
return $this->factories['non_shared_foo']();
Possible Solution
add 'use ($lazyLoad)
to the generated function signature