Fix container injection with TypedReference
This commit is contained in:
parent
a0ac3b0f76
commit
f8c14acd51
@ -904,7 +904,7 @@ EOF;
|
||||
|
||||
$factoryCode = $asFile ? 'self::do($container, false)' : sprintf('$this->%s(false)', $methodName);
|
||||
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
|
||||
$code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
|
||||
$code .= $asFile ? preg_replace('/function \(([^)]*+)\)( {|:)/', 'function (\1) use ($container)\2', $factoryCode) : $factoryCode;
|
||||
}
|
||||
|
||||
$c = $this->addServiceInclude($id, $definition);
|
||||
@ -934,8 +934,7 @@ EOF;
|
||||
|
||||
if ($asFile) {
|
||||
$code = str_replace('$this', '$container', $code);
|
||||
$code = str_replace('function () {', 'function () use ($container) {', $code);
|
||||
$code = str_replace('function ($lazyLoad = true) {', 'function ($lazyLoad = true) use ($container) {', $code);
|
||||
$code = preg_replace('/function \(([^)]*+)\)( {|:)/', 'function (\1) use ($container)\2', $code);
|
||||
}
|
||||
|
||||
$code .= " }\n";
|
||||
|
@ -244,6 +244,26 @@ class PhpDumperTest extends TestCase
|
||||
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
|
||||
}
|
||||
|
||||
public function testDumpAsFilesWithTypedReference()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container10.php';
|
||||
$container->getDefinition('foo')->addTag('hot');
|
||||
$container->register('bar', 'stdClass');
|
||||
$container->register('closure', 'stdClass')
|
||||
->setProperty('closures', [
|
||||
new ServiceClosureArgument(new TypedReference('foo', \stdClass::class, $container::IGNORE_ON_UNINITIALIZED_REFERENCE)),
|
||||
])
|
||||
->setPublic(true);
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$dump = str_replace("'.\\DIRECTORY_SEPARATOR.'", '/', $dump);
|
||||
}
|
||||
|
||||
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services10_as_files.txt', $dump);
|
||||
}
|
||||
|
||||
public function testDumpAsFilesWithFactoriesInlined()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container9.php';
|
||||
|
@ -0,0 +1,167 @@
|
||||
Array
|
||||
(
|
||||
[Container%s/removed-ids.php] => <?php
|
||||
|
||||
namespace Container%s;
|
||||
|
||||
return [
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||
'bar' => true,
|
||||
];
|
||||
|
||||
[Container%s/getClosureService.php] => <?php
|
||||
|
||||
namespace Container%s;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
|
||||
*/
|
||||
class getClosureService extends ProjectServiceContainer
|
||||
{
|
||||
/**
|
||||
* Gets the public 'closure' shared service.
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
public static function do($container, $lazyLoad = true)
|
||||
{
|
||||
$container->services['closure'] = $instance = new \stdClass();
|
||||
|
||||
$instance->closures = [0 => function () use ($container): ?\stdClass {
|
||||
return ($container->services['foo'] ?? null);
|
||||
}];
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
||||
[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;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
/**
|
||||
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
|
||||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
protected $containerDir;
|
||||
protected $targetDir;
|
||||
protected $parameters = [];
|
||||
private $buildParameters;
|
||||
|
||||
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
|
||||
{
|
||||
$this->buildParameters = $buildParameters;
|
||||
$this->containerDir = $containerDir;
|
||||
$this->targetDir = \dirname($containerDir);
|
||||
$this->services = $this->privates = [];
|
||||
$this->methodMap = [
|
||||
'foo' => 'getFooService',
|
||||
];
|
||||
$this->fileMap = [
|
||||
'closure' => 'getClosureService',
|
||||
];
|
||||
|
||||
$this->aliases = [];
|
||||
}
|
||||
|
||||
public function compile(): void
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
public function isCompiled(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRemovedIds(): array
|
||||
{
|
||||
return require $this->containerDir.\DIRECTORY_SEPARATOR.'removed-ids.php';
|
||||
}
|
||||
|
||||
protected function load($file, $lazyLoad = true)
|
||||
{
|
||||
if (class_exists($class = __NAMESPACE__.'\\'.$file, false)) {
|
||||
return $class::do($this, $lazyLoad);
|
||||
}
|
||||
|
||||
if ('.' === $file[-4]) {
|
||||
$class = substr($class, 0, -4);
|
||||
} else {
|
||||
$file .= '.php';
|
||||
}
|
||||
|
||||
$service = require $this->containerDir.\DIRECTORY_SEPARATOR.$file;
|
||||
|
||||
return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo' shared service.
|
||||
*
|
||||
* @return \FooClass
|
||||
*/
|
||||
protected function getFooService()
|
||||
{
|
||||
return $this->services['foo'] = new \FooClass(new \stdClass());
|
||||
}
|
||||
}
|
||||
|
||||
[ProjectServiceContainer.preload.php] => <?php
|
||||
|
||||
// This file has been auto-generated by the Symfony Dependency Injection Component
|
||||
// You can reference it in the "opcache.preload" php.ini setting on PHP >= 7.4 when preloading is desired
|
||||
|
||||
use Symfony\Component\DependencyInjection\Dumper\Preloader;
|
||||
|
||||
if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
require dirname(__DIR__, %d).'%svendor/autoload.php';
|
||||
require __DIR__.'/Container%s/ProjectServiceContainer.php';
|
||||
require __DIR__.'/Container%s/getClosureService.php';
|
||||
|
||||
$classes = [];
|
||||
$classes[] = 'FooClass';
|
||||
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
|
||||
|
||||
Preloader::preload($classes);
|
||||
|
||||
[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