Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d35a530

Browse files
[DI] Put non-shared service factories in closures
1 parent 2aa54b8 commit d35a530

File tree

3 files changed

+39
-21
lines changed

3 files changed

+39
-21
lines changed

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Container implements ResettableContainerInterface
4343
protected $services = array();
4444
protected $fileMap = array();
4545
protected $methodMap = array();
46+
protected $factories = array();
4647
protected $aliases = array();
4748
protected $loading = array();
4849
protected $resolving = array();
@@ -220,6 +221,9 @@ public function get($id, $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERE
220221
if ('service_container' === $id) {
221222
return $this;
222223
}
224+
if (isset($this->factories[$id])) {
225+
return $this->factories[$id]();
226+
}
223227

224228
if (isset($this->loading[$id])) {
225229
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
@@ -289,7 +293,7 @@ public function initialized($id)
289293
*/
290294
public function reset()
291295
{
292-
$this->services = array();
296+
$this->services = $this->factories = array();
293297
}
294298

295299
/**

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ private function addService(string $id, Definition $definition, string &$file =
711711
$lazyInitialization = '';
712712
}
713713

714-
$asFile = $this->asFiles && $definition->isShared() && !$this->isHotPath($definition);
714+
$asFile = $this->asFiles && !$this->isHotPath($definition);
715715
$methodName = $this->generateMethodName($id);
716716
if ($asFile) {
717717
$file = $methodName.'.php';
@@ -785,7 +785,7 @@ private function addServices(): string
785785
$definitions = $this->container->getDefinitions();
786786
ksort($definitions);
787787
foreach ($definitions as $id => $definition) {
788-
if ($definition->isSynthetic() || ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition))) {
788+
if ($definition->isSynthetic() || ($this->asFiles && !$this->isHotPath($definition))) {
789789
continue;
790790
}
791791
if ($definition->isPublic()) {
@@ -803,8 +803,14 @@ private function generateServiceFiles()
803803
$definitions = $this->container->getDefinitions();
804804
ksort($definitions);
805805
foreach ($definitions as $id => $definition) {
806-
if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) {
806+
if (!$definition->isSynthetic() && !$this->isHotPath($definition)) {
807807
$code = $this->addService($id, $definition, $file);
808+
809+
if (!$definition->isShared()) {
810+
$factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id);
811+
$code = sprintf("\n%s = function () {\n%s};\n\nreturn %1\$s();\n", $factory, $code);
812+
}
813+
808814
yield $file => $code;
809815
}
810816
}
@@ -1036,7 +1042,7 @@ private function addMethodMap(): string
10361042
$definitions = $this->container->getDefinitions();
10371043
ksort($definitions);
10381044
foreach ($definitions as $id => $definition) {
1039-
if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) {
1045+
if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->isHotPath($definition))) {
10401046
$code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n";
10411047
}
10421048
}
@@ -1050,7 +1056,7 @@ private function addFileMap(): string
10501056
$definitions = $this->container->getDefinitions();
10511057
ksort($definitions);
10521058
foreach ($definitions as $id => $definition) {
1053-
if (!$definition->isSynthetic() && $definition->isPublic() && $definition->isShared() && !$this->isHotPath($definition)) {
1059+
if (!$definition->isSynthetic() && $definition->isPublic() && !$this->isHotPath($definition)) {
10541060
$code .= sprintf(" %s => __DIR__.'/%s.php',\n", $this->doExport($id), $this->generateMethodName($id));
10551061
}
10561062
}
@@ -1183,9 +1189,9 @@ public function getParameterBag()
11831189
}
11841190

11851191
EOF;
1186-
if (!$this->asFiles) {
1187-
$code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code);
1188-
}
1192+
if (!$this->asFiles) {
1193+
$code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code);
1194+
}
11891195

11901196
if ($dynamicPhp) {
11911197
$loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8);
@@ -1621,8 +1627,12 @@ private function getServiceCall(string $id, Reference $reference = null): string
16211627
if ($definition->isShared()) {
16221628
$code = sprintf('$this->%s[\'%s\'] = %s', $definition->isPublic() ? 'services' : 'privates', $id, $code);
16231629
}
1624-
} elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) {
1630+
} elseif ($this->asFiles && !$this->isHotPath($definition)) {
16251631
$code = sprintf("\$this->load(__DIR__.'/%s.php')", $this->generateMethodName($id));
1632+
if (!$definition->isShared()) {
1633+
$factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id);
1634+
$code = sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code);
1635+
}
16261636
} else {
16271637
$code = sprintf('$this->%s()', $this->generateMethodName($id));
16281638
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ $this->services['foo.baz'] = $instance = \BazClass::getInstance();
179179

180180
return $instance;
181181

182+
[Container%s/getFooBarService.php] => <?php
183+
184+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
185+
186+
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
187+
188+
$this->factories['foo_bar'] = function () {
189+
// Returns the public 'foo_bar' service.
190+
191+
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->load(__DIR__.'/getDeprecatedServiceService.php')));
192+
};
193+
194+
return $this->factories['foo_bar']();
195+
182196
[Container%s/getFooWithInlineService.php] => <?php
183197

184198
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
@@ -331,7 +345,6 @@ class ProjectServiceContainer extends Container
331345
);
332346
$this->methodMap = array(
333347
'bar' => 'getBarService',
334-
'foo_bar' => 'getFooBarService',
335348
);
336349
$this->fileMap = array(
337350
'BAR' => __DIR__.'/getBAR2Service.php',
@@ -347,6 +360,7 @@ class ProjectServiceContainer extends Container
347360
'factory_service_simple' => __DIR__.'/getFactoryServiceSimpleService.php',
348361
'foo' => __DIR__.'/getFooService.php',
349362
'foo.baz' => __DIR__.'/getFoo_BazService.php',
363+
'foo_bar' => __DIR__.'/getFooBarService.php',
350364
'foo_with_inline' => __DIR__.'/getFooWithInlineService.php',
351365
'lazy_context' => __DIR__.'/getLazyContextService.php',
352366
'lazy_context_ignore_invalid_ref' => __DIR__.'/getLazyContextIgnoreInvalidRefService.php',
@@ -404,16 +418,6 @@ class ProjectServiceContainer extends Container
404418
return $instance;
405419
}
406420

407-
/**
408-
* Gets the public 'foo_bar' service.
409-
*
410-
* @return \Bar\FooClass
411-
*/
412-
protected function getFooBarService()
413-
{
414-
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->load(__DIR__.'/getDeprecatedServiceService.php')));
415-
}
416-
417421
public function getParameter($name)
418422
{
419423
$name = (string) $name;

0 commit comments

Comments
 (0)