Skip to content

Commit d1d4105

Browse files
matej21dg
authored andcommitted
ContainerBuilder::getClassList: optimized performance [Closes #108]
1 parent ceb472a commit d1d4105

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

src/DI/ContainerBuilder.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class ContainerBuilder
3939
/** @var array for auto-wiring */
4040
private $classList = FALSE;
4141

42+
/** @var bool */
43+
private $classListNeedsRefresh = TRUE;
44+
4245
/** @var string[] of classes excluded from auto-wiring */
4346
private $excludedClasses = [];
4447

@@ -59,14 +62,21 @@ class ContainerBuilder
5962
*/
6063
public function addDefinition($name, ServiceDefinition $definition = NULL)
6164
{
65+
$this->classListNeedsRefresh = TRUE;
6266
if (!is_string($name) || !$name) { // builder is not ready for falsy names such as '0'
6367
throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($name)));
6468
}
6569
$name = isset($this->aliases[$name]) ? $this->aliases[$name] : $name;
6670
if (isset($this->definitions[$name])) {
6771
throw new Nette\InvalidStateException("Service '$name' has already been added.");
6872
}
69-
return $this->definitions[$name] = $definition ?: new ServiceDefinition;
73+
if (!$definition) {
74+
$definition = new ServiceDefinition;
75+
}
76+
$definition->setNotifier(function () {
77+
$this->classListNeedsRefresh = TRUE;
78+
});
79+
return $this->definitions[$name] = $definition;
7080
}
7181

7282

@@ -77,6 +87,7 @@ public function addDefinition($name, ServiceDefinition $definition = NULL)
7787
*/
7888
public function removeDefinition($name)
7989
{
90+
$this->classListNeedsRefresh = TRUE;
8091
$name = isset($this->aliases[$name]) ? $this->aliases[$name] : $name;
8192
unset($this->definitions[$name]);
8293
}
@@ -258,10 +269,9 @@ public function findByTag($tag)
258269

259270
private function getClassList()
260271
{
261-
static $prev;
262-
if ($this->classList !== FALSE && $prev !== serialize($this->definitions)) {
272+
if ($this->classList !== FALSE && $this->classListNeedsRefresh) {
263273
$this->prepareClassList();
264-
$prev = serialize($this->definitions);
274+
$this->classListNeedsRefresh = FALSE;
265275
}
266276
return $this->classList ?: [];
267277
}

src/DI/ServiceDefinition.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,16 @@ class ServiceDefinition
4848
/** @var string|NULL create | get */
4949
private $implementType;
5050

51+
/** @var callable */
52+
private $notifier = 'pi'; // = noop
53+
5154

5255
/**
5356
* @return self
5457
*/
5558
public function setClass($class, array $args = [])
5659
{
60+
call_user_func($this->notifier);
5761
$this->class = $class ? ltrim($class, '\\') : NULL;
5862
if ($args) {
5963
$this->setFactory($class, $args);
@@ -76,6 +80,7 @@ public function getClass()
7680
*/
7781
public function setFactory($factory, array $args = [])
7882
{
83+
call_user_func($this->notifier);
7984
$this->factory = $factory instanceof Statement ? $factory : new Statement($factory, $args);
8085
return $this;
8186
}
@@ -210,6 +215,7 @@ public function getTag($tag)
210215
*/
211216
public function setAutowired($state = TRUE)
212217
{
218+
call_user_func($this->notifier);
213219
$this->autowired = (bool) $state;
214220
return $this;
215221
}
@@ -250,6 +256,7 @@ public function isDynamic()
250256
*/
251257
public function setImplement($interface)
252258
{
259+
call_user_func($this->notifier);
253260
$this->implement = ltrim($interface, '\\');
254261
return $this;
255262
}
@@ -303,10 +310,20 @@ public function getInject()
303310
}
304311

305312

313+
/**
314+
* @internal
315+
*/
316+
public function setNotifier(callable $notifier)
317+
{
318+
$this->notifier = $notifier;
319+
}
320+
321+
306322
public function __clone()
307323
{
308324
$this->factory = unserialize(serialize($this->factory));
309325
$this->setup = unserialize(serialize($this->setup));
326+
$this->notifier = NULL;
310327
}
311328

312329
}

0 commit comments

Comments
 (0)