File tree 5 files changed +94
-1
lines changed
5 files changed +94
-1
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ CHANGELOG
7
7
* allowed specifying a directory to recursively load all configuration files it contains
8
8
* deprecated the concept of scopes
9
9
* added ` Definition::setShared() ` and ` Definition::isShared() `
10
+ * added ResettableContainerInterface to be able to reset the container to release memory on shutdown
10
11
11
12
2.7.0
12
13
-----
Original file line number Diff line number Diff line change 13
13
14
14
use Symfony \Component \DependencyInjection \Exception \InactiveScopeException ;
15
15
use Symfony \Component \DependencyInjection \Exception \InvalidArgumentException ;
16
+ use Symfony \Component \DependencyInjection \Exception \LogicException ;
16
17
use Symfony \Component \DependencyInjection \Exception \RuntimeException ;
17
18
use Symfony \Component \DependencyInjection \Exception \ServiceNotFoundException ;
18
19
use Symfony \Component \DependencyInjection \Exception \ServiceCircularReferenceException ;
60
61
*
61
62
* @api
62
63
*/
63
- class Container implements IntrospectableContainerInterface
64
+ class Container implements IntrospectableContainerInterface, ResettableContainerInterface
64
65
{
65
66
/**
66
67
* @var ParameterBagInterface
@@ -375,6 +376,18 @@ public function initialized($id)
375
376
return isset ($ this ->services [$ id ]) || array_key_exists ($ id , $ this ->services );
376
377
}
377
378
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
+
378
391
/**
379
392
* Gets all service ids.
380
393
*
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
+ * 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()
320
320
$ this ->assertTrue ($ sc ->initialized ('alias ' ), '->initialized() returns true for alias if aliased service is initialized ' );
321
321
}
322
322
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
+
323
366
/**
324
367
* @group legacy
325
368
*/
Original file line number Diff line number Diff line change 23
23
use Symfony \Component \DependencyInjection \Loader \PhpFileLoader ;
24
24
use Symfony \Component \DependencyInjection \Loader \DirectoryLoader ;
25
25
use Symfony \Component \DependencyInjection \Loader \ClosureLoader ;
26
+ use Symfony \Component \DependencyInjection \ResettableContainerInterface ;
26
27
use Symfony \Component \HttpFoundation \Request ;
27
28
use Symfony \Component \HttpFoundation \Response ;
28
29
use Symfony \Component \HttpKernel \Bundle \BundleInterface ;
@@ -180,6 +181,10 @@ public function shutdown()
180
181
$ bundle ->setContainer (null );
181
182
}
182
183
184
+ if ($ this ->container instanceof ResettableContainerInterface) {
185
+ $ this ->container ->reset ();
186
+ }
187
+
183
188
$ this ->container = null ;
184
189
}
185
190
You can’t perform that action at this time.
0 commit comments