public function prepareClassList()
{
unset($this->definitions[self::THIS_CONTAINER]);
$this->addDefinition(self::THIS_CONTAINER)->setClass(Container::class);
$this->classList = FALSE;
foreach ($this->definitions as $name => $def) {
// prepare generated factories
if ($def->getImplement()) {
$this->resolveImplement($def, $name);
}
if ($def->isDynamic()) {
if (!$def->getClass()) {
throw new ServiceCreationException("Class is missing in definition of service '{$name}'.");
}
$def->setFactory(NULL);
continue;
}
// complete class-factory pairs
if (!$def->getEntity()) {
if (!$def->getClass()) {
throw new ServiceCreationException("Class and factory are missing in definition of service '{$name}'.");
}
$def->setFactory($def->getClass(), ($factory = $def->getFactory()) ? $factory->arguments : []);
}
// auto-disable autowiring for aliases
if (($alias = $this->getServiceName($def->getFactory()->getEntity())) && (!$def->getImplement() || !Strings::contains($alias, '\\') && $this->definitions[$alias]->getImplement())) {
$def->setAutowired(FALSE);
}
}
// resolve and check classes
foreach ($this->definitions as $name => $def) {
$this->resolveServiceClass($name);
}
// build auto-wiring list
$this->classList = $preferred = [];
foreach ($this->definitions as $name => $def) {
if ($class = $def->getImplement() ?: $def->getClass()) {
$defAutowired = $def->getAutowired();
if (is_array($defAutowired)) {
foreach ($defAutowired as $k => $aclass) {
if ($aclass === self::THIS_SERVICE) {
$defAutowired[$k] = $class;
} elseif (!is_a($class, $aclass, TRUE)) {
throw new ServiceCreationException("Incompatible class {$aclass} in autowiring definition of service '{$name}'.");
}
}
}
foreach (class_parents($class) + class_implements($class) + [$class] as $parent) {
$autowired = $defAutowired && empty($this->excludedClasses[$parent]);
if ($autowired && is_array($defAutowired)) {
$autowired = FALSE;
foreach ($defAutowired as $aclass) {
if (is_a($parent, $aclass, TRUE)) {
if (empty($preferred[$parent]) && isset($this->classList[$parent][TRUE])) {
$this->classList[$parent][FALSE] = array_merge(...$this->classList[$parent]);
$this->classList[$parent][TRUE] = [];
}
$preferred[$parent] = $autowired = TRUE;
break;
}
}
} elseif (isset($preferred[$parent])) {
$autowired = FALSE;
}
$this->classList[$parent][$autowired][] = (string) $name;
}
}
}
}