src/Container.php
protected function applyInitializers(object $object): object
    {
        $typeName = \get_class($object);
        $definition = $this->definitions[$typeName] ?? null;
        
        if ($definition === null || $definition->injector === null) {
            $current = $typeName;
            $inheritance = [];
            
            do {
                if (empty($this->definitions[$current])) {
                    $this->definitions[$current] = new Definition($current);
                }
                
                $inheritance[] = $this->definitions[$current];
                $current = \get_parent_class($current);
            } while ($current !== false);
            
            $definition = null;
            
            for ($i = \count($inheritance) - 1; $i >= 0; $i--) {
                $prev = $definition;
                $definition = $inheritance[$i];
                
                if ($definition->injector !== null) {
                    continue;
                }
                
                if ($definition->injects) {
                    if ($prev && $prev->injects) {
                        $definition->injects = \array_merge($prev->injects, $definition->injects);
                    }
                } else {
                    $definition->injects = $prev ? $prev->injects : null;
                }
                
                if (!$definition->injects) {
                    $definition->injector = false;
                    
                    continue;
                }
                
                foreach ($definition->injects as $method => & $v) {
                    if ($v !== true) {
                        continue;
                    }
                    
                    $ref = new \ReflectionMethod($definition->typeName, $method);
                    
                    if (!$ref->isPublic()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must be public', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    if ($ref->isStatic()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must not be static', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    if ($ref->getNumberOfParameters() !== 1) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must declare exactly 1 argument', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    $param = $ref->getParameters()[0];
                    
                    if (!$param->hasType()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must declare an injected type', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    $type = $param->getType();
                    
                    $v = [
                        $type->getName(),
                        $type->allowsNull(),
                        $ref->getDeclaringClass()->getName()
                    ];
                }
                
                unset($v);
                
                $definition->injector = static function (object $object, Container $container) use ($definition): object {
                    $impl = \get_class($object);
                    
                    foreach ($definition->injects as $method => list ($type, $nullable, $decl)) {
                        $result = $object->$method($container->get($type, $nullable, $impl));
                        
                        if ($result === $object) {
                            throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must return a new object instance', $decl, $method));
                        }
                        
                        if (!$result instanceof $impl) {
                            throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must return an object of type %s', $decl, $method, $impl));
                        }
                        
                        $object = $result;
                    }
                    
                    return $object;
                };
            }
        }
        
        if ($definition->injects) {
            $object = ($definition->injector)($object, $this);
        }
        
        if ($object instanceof LoggerAwareInterface) {
            $object->setLogger($this->shared[LoggerInterface::class] ?? $this->get(LoggerInterface::class));
        }
        
        return $object;
    }
protected function applyInitializers(object $object): object
    {
        $typeName = \get_class($object);
        $definition = $this->definitions[$typeName] ?? null;
        
        if ($definition === null || $definition->injector === null) {
            $current = $typeName;
            $inheritance = [];
            
            do {
                if (empty($this->definitions[$current])) {
                    $this->definitions[$current] = new Definition($current);
                }
                
                $inheritance[] = $this->definitions[$current];
                $current = \get_parent_class($current);
            } while ($current !== false);
            
            $definition = null;
            
            for ($i = \count($inheritance) - 1; $i >= 0; $i--) {
                $prev = $definition;
                $definition = $inheritance[$i];
                
                if ($definition->injector !== null) {
                    continue;
                }
                
                if ($definition->injects) {
                    if ($prev && $prev->injects) {
                        $definition->injects = \array_merge($prev->injects, $definition->injects);
                    }
                } else {
                    $definition->injects = $prev ? $prev->injects : null;
                }
                
                if (!$definition->injects) {
                    $definition->injector = false;
                    
                    continue;
                }
                
                foreach ($definition->injects as $method => & $v) {
                    if ($v !== true) {
                        continue;
                    }
                    
                    $ref = new \ReflectionMethod($definition->typeName, $method);
                    
                    if (!$ref->isPublic()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must be public', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    if ($ref->isStatic()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must not be static', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    if ($ref->getNumberOfParameters() !== 1) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must declare exactly 1 argument', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    $param = $ref->getParameters()[0];
                    
                    if (!$param->hasType()) {
                        throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must declare an injected type', $ref->getDeclaringClass()->getName(), $method));
                    }
                    
                    $type = $param->getType();
                    
                    $v = [
                        $type->getName(),
                        $type->allowsNull(),
                        $ref->getDeclaringClass()->getName()
                    ];
                }
                
                unset($v);
                
                $definition->injector = static function (object $object, Container $container) use ($definition): object {
                    $impl = \get_class($object);
                    
                    foreach ($definition->injects as $method => list ($type, $nullable, $decl)) {
                        $result = $object->$method($container->get($type, $nullable, $impl));
                        
                        if ($result === $object) {
                            throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must return a new object instance', $decl, $method));
                        }
                        
                        if (!$result instanceof $impl) {
                            throw new \RuntimeException(\sprintf('Mutator injector %s->%s() must return an object of type %s', $decl, $method, $impl));
                        }
                        
                        $object = $result;
                    }
                    
                    return $object;
                };
            }
        }
        
        if ($definition->injects) {
            $object = ($definition->injector)($object, $this);
        }
        
        if ($object instanceof LoggerAwareInterface) {
            $object->setLogger($this->shared[LoggerInterface::class] ?? $this->get(LoggerInterface::class));
        }
        
        return $object;
    }
Inject additional dependencies into an object.