File tree Expand file tree Collapse file tree 5 files changed +89
-1
lines changed Expand file tree Collapse file tree 5 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 6060 *
6161 * @api
6262 */
63- class Container implements IntrospectableContainerInterface
63+ class Container implements IntrospectableContainerInterface, ResettableContainerInterface
6464{
6565 /**
6666 * @var ParameterBagInterface
@@ -375,6 +375,18 @@ public function initialized($id)
375375 return isset ($ this ->services [$ id ]) || array_key_exists ($ id , $ this ->services );
376376 }
377377
378+ /**
379+ * Clears shared services from the container.
380+ */
381+ public function reset ()
382+ {
383+ if (!empty ($ this ->scopedServices )) {
384+ throw new RuntimeException ('Resetting the container is not allowed when a scope is active. ' );
385+ }
386+
387+ $ this ->services = array ();
388+ }
389+
378390 /**
379391 * Gets all service ids.
380392 *
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 <[email protected] > 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 <[email protected] > 20+ */
21+ interface ResettableContainerInterface extends ContainerInterface
22+ {
23+ /**
24+ * Resets shared services from the container.
25+ */
26+ public function reset ();
27+ }
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\RuntimeException
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 */
Original file line number Diff line number Diff line change 1313
1414use Symfony \Bridge \ProxyManager \LazyProxy \Instantiator \RuntimeInstantiator ;
1515use Symfony \Bridge \ProxyManager \LazyProxy \PhpDumper \ProxyDumper ;
16+ use Symfony \Component \DependencyInjection \ResettableContainerInterface ;
1617use Symfony \Component \DependencyInjection \ContainerInterface ;
1718use Symfony \Component \DependencyInjection \ContainerBuilder ;
1819use Symfony \Component \DependencyInjection \Dumper \PhpDumper ;
@@ -180,6 +181,10 @@ public function shutdown()
180181 $ bundle ->setContainer (null );
181182 }
182183
184+ if ($ this ->container instanceof ResettableContainerInterface) {
185+ $ this ->container ->reset ();
186+ }
187+
183188 $ this ->container = null ;
184189 }
185190
You can’t perform that action at this time.
0 commit comments