Skip to content

Commit d314b1f

Browse files
[DI] Allow setting any public non-initialized services
1 parent b87a395 commit d314b1f

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ public function set($id, $service)
190190
unset($this->aliases[$id]);
191191
}
192192

193+
$wasSet = isset($this->services[$id]);
193194
$this->services[$id] = $service;
194195

195196
if (null === $service) {
@@ -203,11 +204,11 @@ public function set($id, $service)
203204
} else {
204205
@trigger_error(sprintf('Setting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
205206
}
206-
} elseif (isset($this->methodMap[$id])) {
207+
} elseif ($wasSet && isset($this->methodMap[$id])) {
207208
if (null === $service) {
208-
@trigger_error(sprintf('Unsetting the "%s" pre-defined service is deprecated since Symfony 3.3 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
209+
@trigger_error(sprintf('Unsetting the "%s" service after it\'s been initialized is deprecated since Symfony 3.3 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
209210
} else {
210-
@trigger_error(sprintf('Setting the "%s" pre-defined service is deprecated since Symfony 3.3 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
211+
@trigger_error(sprintf('Setting the "%s" service after it\'s been initialized is deprecated since Symfony 3.3 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
211212
}
212213
}
213214
}

src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,29 @@ public function testSetReplacesAlias()
186186

187187
/**
188188
* @group legacy
189-
* @expectedDeprecation Unsetting the "bar" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
189+
* @expectedDeprecation Unsetting the "bar" service after it's been initialized is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
190190
*/
191-
public function testSetWithNullResetPredefinedService()
191+
public function testSetWithNullOnInitializedPredefinedService()
192192
{
193193
$sc = new Container();
194194
$sc->set('foo', new \stdClass());
195195
$sc->set('foo', null);
196196
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
197197

198+
$sc = new ProjectServiceContainer();
199+
$sc->get('bar');
200+
$sc->set('bar', null);
201+
$this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
202+
}
203+
204+
public function testSetWithNullOnUninitializedPredefinedService()
205+
{
206+
$sc = new Container();
207+
$sc->set('foo', new \stdClass());
208+
$sc->get('foo', null);
209+
$sc->set('foo', null);
210+
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
211+
198212
$sc = new ProjectServiceContainer();
199213
$sc->set('bar', null);
200214
$this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
@@ -481,7 +495,7 @@ public function testRequestAnInternalSharedPrivateServiceIsDeprecated()
481495

482496
/**
483497
* @group legacy
484-
* @expectedDeprecation Setting the "bar" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
498+
* @expectedDeprecation Setting the "bar" service after it's been initialized is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
485499
*/
486500
public function testReplacingAPreDefinedServiceIsDeprecated()
487501
{

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,23 +269,24 @@ public function testFrozenContainerWithoutAliases()
269269

270270
/**
271271
* @group legacy
272-
* @expectedDeprecation Setting the "bar" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
272+
* @expectedDeprecation Setting the "bar" service after it's been initialized is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
273273
*/
274274
public function testOverrideServiceWhenUsingADumpedContainer()
275275
{
276276
require_once self::$fixturesPath.'/php/services9.php';
277277
require_once self::$fixturesPath.'/includes/foo.php';
278278

279279
$container = new \ProjectServiceContainer();
280-
$container->set('bar', $bar = new \stdClass());
281280
$container->setParameter('foo_bar', 'foo_bar');
281+
$container->get('bar');
282+
$container->set('bar', $bar = new \stdClass());
282283

283284
$this->assertSame($bar, $container->get('bar'), '->set() overrides an already defined service');
284285
}
285286

286287
/**
287288
* @group legacy
288-
* @expectedDeprecation Setting the "bar" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
289+
* @expectedDeprecation Setting the "bar" service after it's been initialized is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0.
289290
*/
290291
public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFromAnotherOne()
291292
{
@@ -294,6 +295,8 @@ public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFrom
294295
require_once self::$fixturesPath.'/includes/classes.php';
295296

296297
$container = new \ProjectServiceContainer();
298+
$container->setParameter('foo_bar', 'foo_bar');
299+
$container->get('bar');
297300
$container->set('bar', $bar = new \stdClass());
298301

299302
$this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service');

0 commit comments

Comments
 (0)