Nette\DI\ContainerBuilder::resolveImplement PHP Метод

resolveImplement() приватный Метод

private resolveImplement ( ServiceDefinition $def, $name )
$def ServiceDefinition
    private function resolveImplement(ServiceDefinition $def, $name)
    {
        $interface = $def->getImplement();
        if (!interface_exists($interface)) {
            throw new ServiceCreationException("Interface {$interface} used in service '{$name}' not found.");
        }
        self::checkCase($interface);
        $rc = new ReflectionClass($interface);
        $this->addDependency($rc);
        $method = $rc->hasMethod('create') ? $rc->getMethod('create') : ($rc->hasMethod('get') ? $rc->getMethod('get') : NULL);
        if (count($rc->getMethods()) !== 1 || !$method || $method->isStatic()) {
            throw new ServiceCreationException("Interface {$interface} used in service '{$name}' must have just one non-static method create() or get().");
        }
        $def->setImplementMode($methodName = $rc->hasMethod('create') ? $def::IMPLEMENT_MODE_CREATE : $def::IMPLEMENT_MODE_GET);
        if (!$def->getClass() && !$def->getEntity()) {
            $returnType = PhpReflection::getReturnType($method);
            if (!$returnType) {
                throw new ServiceCreationException("Method {$interface}::{$methodName}() used in service '{$name}' has no @return annotation.");
            } elseif (!class_exists($returnType)) {
                throw new ServiceCreationException("Check a @return annotation of the {$interface}::{$methodName}() method used in service '{$name}', class '{$returnType}' cannot be found.");
            }
            $def->setClass($returnType);
        }
        if ($methodName === 'get') {
            if ($method->getParameters()) {
                throw new ServiceCreationException("Method {$interface}::get() used in service '{$name}' must have no arguments.");
            }
            if (!$def->getEntity()) {
                $def->setFactory('@\\' . ltrim($def->getClass(), '\\'));
            } elseif (!$this->getServiceName($def->getFactory()->getEntity())) {
                throw new ServiceCreationException("Invalid factory in service '{$name}' definition.");
            }
        }
        if (!$def->parameters) {
            $ctorParams = [];
            if (!$def->getEntity()) {
                $def->setFactory($def->getClass(), $def->getFactory() ? $def->getFactory()->arguments : []);
            }
            if (($class = $this->resolveEntityClass($def->getFactory(), [$name => 1])) && ($ctor = (new ReflectionClass($class))->getConstructor())) {
                foreach ($ctor->getParameters() as $param) {
                    $ctorParams[$param->getName()] = $param;
                }
            }
            foreach ($method->getParameters() as $param) {
                $hint = PhpReflection::getParameterType($param);
                if (isset($ctorParams[$param->getName()])) {
                    $arg = $ctorParams[$param->getName()];
                    if ($hint !== PhpReflection::getParameterType($arg)) {
                        throw new ServiceCreationException("Type hint for \${$param->getName()} in {$interface}::{$methodName}() doesn't match type hint in {$class} constructor.");
                    }
                    $def->getFactory()->arguments[$arg->getPosition()] = self::literal('$' . $arg->getName());
                } elseif (!$def->getSetup()) {
                    $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($ctorParams), $param->getName());
                    throw new ServiceCreationException("Unused parameter \${$param->getName()} when implementing method {$interface}::{$methodName}()" . ($hint ? ", did you mean \${$hint}?" : '.'));
                }
                $paramDef = $hint . ' ' . $param->getName();
                if ($param->isDefaultValueAvailable()) {
                    $def->parameters[$paramDef] = $param->getDefaultValue();
                } else {
                    $def->parameters[] = $paramDef;
                }
            }
        }
    }