File tree Expand file tree Collapse file tree 4 files changed +89
-1
lines changed Expand file tree Collapse file tree 4 files changed +89
-1
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ CHANGELOG
77 * allowed specifying a directory to recursively load all configuration files it contains
88 * deprecated the concept of scopes
99 * added ` Definition::setShared() ` and ` Definition::isShared() `
10+ * added ResettableContainerInterface to be able to reset the container to release memory on shutdown
1011
11122.7.0
1213-----
Original file line number Diff line number Diff line change 1313
1414use Symfony \Component \DependencyInjection \Exception \InactiveScopeException ;
1515use Symfony \Component \DependencyInjection \Exception \InvalidArgumentException ;
16+ use Symfony \Component \DependencyInjection \Exception \LogicException ;
1617use Symfony \Component \DependencyInjection \Exception \RuntimeException ;
1718use Symfony \Component \DependencyInjection \Exception \ServiceNotFoundException ;
1819use Symfony \Component \DependencyInjection \Exception \ServiceCircularReferenceException ;
6061 *
6162 * @api
6263 */
63- class Container implements IntrospectableContainerInterface
64+ class Container implements IntrospectableContainerInterface, ResettableContainerInterface
6465{
6566 /**
6667 * @var ParameterBagInterface
@@ -375,6 +376,18 @@ public function initialized($id)
375376 return isset ($ this ->services [$ id ]) || array_key_exists ($ id , $ this ->services );
376377 }
377378
379+ /**
380+ * {@inheritdoc}
381+ */
382+ public function reset ()
383+ {
384+ if (!empty ($ this ->scopedServices )) {
385+ throw new LogicException ('Resetting the container is not allowed when a scope is active. ' );
386+ }
387+
388+ $ this ->services = array ();
389+ }
390+
378391 /**
379392 * Gets all service ids.
380393 *
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ /*
4+ * This file is part of the Symfony package.
5+ *
6+ * (c) Fabien Potencier <fabien@symfony.com>
7+ *
8+ * For the full copyright and license information, please view the LICENSE
9+ * file that was distributed with this source code.
10+ */
11+
12+ namespace Symfony \Component \DependencyInjection ;
13+
14+ /**
15+ * ResettableContainerInterface defines additional resetting functionality
16+ * for containers, allowing to release shared services when the container is
17+ * not needed anymore.
18+ *
19+ * @author Christophe Coevoet <stof@notk.org>
20+ */
21+ interface ResettableContainerInterface extends ContainerInterface
22+ {
23+ /**
24+ * Resets shared services from the container.
25+ *
26+ * The container is not intended to be used again after being reset in a normal workflow. This method is
27+ * meant as a way to release references for ref-counting.
28+ * A subsequent call to ContainerInterface::get will recreate a new instance of the shared service.
29+ */
30+ public function reset ();
31+ }
Original file line number Diff line number Diff line change @@ -320,6 +320,49 @@ public function testInitialized()
320320 $ this ->assertTrue ($ sc ->initialized ('alias ' ), '->initialized() returns true for alias if aliased service is initialized ' );
321321 }
322322
323+ public function testReset ()
324+ {
325+ $ c = new Container ();
326+ $ c ->set ('bar ' , new \stdClass ());
327+
328+ $ c ->reset ();
329+
330+ $ this ->assertNull ($ c ->get ('bar ' , ContainerInterface::NULL_ON_INVALID_REFERENCE ));
331+ }
332+
333+ /**
334+ * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
335+ * @expectedExceptionMessage Resetting the container is not allowed when a scope is active.
336+ * @group legacy
337+ */
338+ public function testCannotResetInActiveScope ()
339+ {
340+ $ c = new Container ();
341+ $ c ->addScope (new Scope ('foo ' ));
342+ $ c ->set ('bar ' , new \stdClass ());
343+
344+ $ c ->enterScope ('foo ' );
345+
346+ $ c ->reset ();
347+ }
348+
349+ /**
350+ * @group legacy
351+ */
352+ public function testResetAfterLeavingScope ()
353+ {
354+ $ c = new Container ();
355+ $ c ->addScope (new Scope ('foo ' ));
356+ $ c ->set ('bar ' , new \stdClass ());
357+
358+ $ c ->enterScope ('foo ' );
359+ $ c ->leaveScope ('foo ' );
360+
361+ $ c ->reset ();
362+
363+ $ this ->assertNull ($ c ->get ('bar ' , ContainerInterface::NULL_ON_INVALID_REFERENCE ));
364+ }
365+
323366 /**
324367 * @group legacy
325368 */
You can’t perform that action at this time.
0 commit comments