Shares a given service in the container.

@param Definition  $definition
@param mixed       $service
@param string|null $id
189625
private function shareService(Definition $definition, $service, $id)
    {
        if (null !== $id && $definition->isShared()) {
            $this->services[strtolower($id)] = $service;
        }
    }
1164970
protected function processService(Element $service, $namespace = null) {
		$definition = new stdClass();
		
		if (isset($service->class)) {
			$definition->type  = 'class';
			$definition->class = ($namespace === null)
				? $service->class
				: $namespace . '\\' . $service->class;
		}
		
		if ($service->factory === 'true') {
			$definition->factory = true;
		}
		
		$content = $service->getContent();
		
		if (! empty($content)) {
			$this->processDefinitionParameters($content, $definition);
		}
		
		return $definition;
	}
1351684
public function protect(string $id, $definition, $share = false)
    {
        return $this->lock($id, $definition, $share);
    }
699380
private function populateAvailableType(ContainerBuilder $container, string $id, Definition $definition)
    {
        // Never use abstract services
        if ($definition->isAbstract()) {
            return;
        }

        if ('' === $id || '.' === $id[0] || $definition->isDeprecated() || !$reflectionClass = $container->getReflectionClass($definition->getClass(), false)) {
            return;
        }

        foreach ($reflectionClass->getInterfaces() as $reflectionInterface) {
            $this->set($reflectionInterface->name, $id);
        }

        do {
            $this->set($reflectionClass->name, $id);
        } while ($reflectionClass = $reflectionClass->getParentClass());
    }
1291269
public function set($id, $definition, array $params = [], $share = true)
    {        
        // 设置对象实例（非闭包函数）则保存实例
        if (is_object($definition) && !($definition instanceof \Closure)) {
            // object
            $this->services[$id] = $definition;
            $definition = get_class($definition);
        } elseif (!is_string($definition) && !($definition instanceof \Closure)) {
            // 检查字符串（类目）、闭包函数
            // 不是 object/Closure/string 则抛出异常
            throw new \InvalidArgumentException('The $definition argumet type must be "class name/object/Closure", the given is ' . var_export($definition, true));
        }
        
        $this->definitions[$id] = $definition;
        $this->params[$id] = $params;
        $this->shareds[$id] = $share;
        
        return $this;
    }
103332
public function haveServiceInDi($name, $definition, $shared = false)
    {
        return $this->addServiceToContainer($name, $definition, $shared);
    }
109513
private function addServiceInlinedDefinitions($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, &$isSimpleInstance)
    {
        $code = '';

        foreach ($inlinedDefinitions as $def) {
            if ($definition === $def) {
                continue;
            }
            if ($inlinedDefinitions[$def] <= 1 && !$def->getMethodCalls() && !$def->getProperties() && !$def->getConfigurator() && false === strpos($this->dumpValue($def->getClass()), '$')) {
                continue;
            }
            if (isset($this->definitionVariables[$def])) {
                $name = $this->definitionVariables[$def];
            } else {
                $name = $this->getNextVariableName();
                $this->definitionVariables[$def] = new Variable($name);
            }

            // a construct like:
            // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a);
            // this is an indication for a wrong implementation, you can circumvent this problem
            // by setting up your service structure like this:
            // $b = new ServiceB();
            // $a = new ServiceA(ServiceB $b);
            // $b->setServiceA(ServiceA $a);
            if (isset($inlinedDefinition[$definition]) && $this->hasReference($id, array($def->getArguments(), $def->getFactory()))) {
                throw new ServiceCircularReferenceException($id, array($id));
            }

            $code .= $this->addNewInstance($def, '$'.$name, ' = ', $id);

            if (!$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) {
                $code .= $this->addServiceProperties($def, $name);
                $code .= $this->addServiceMethodCalls($def, $name);
                $code .= $this->addServiceConfigurator($def, $name);
            } else {
                $isSimpleInstance = false;
            }

            $code .= "\n";
        }

        return $code;
    }
273392
protected function parseService($id, $service, $file)
    {
        if ((string) $service['alias']) {
            $public = true;
            if (isset($service['public'])) {
                $public = $this->getAttributeAsPhp($service, 'public');
            }
            $this->container->setAlias($id, new Alias((string) $service['alias'], $public));

            return;
        }

        if (isset($service['parent'])) {
            $definition = new DefinitionDecorator((string) $service['parent']);
        } else {
            $definition = new Definition();
        }

        foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'abstract') as $key) {
            if (isset($service[$key])) {
                $method = 'set'.str_replace('-', '', $key);
                $definition->$method((string) $this->getAttributeAsPhp($service, $key));
            }
        }

        if ($service->file) {
            $definition->setFile((string) $service->file);
        }

        $definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
        $definition->setProperties($this->getArgumentsAsPhp($service, 'property'));

        if (isset($service->configurator)) {
            if (isset($service->configurator['function'])) {
                $definition->setConfigurator((string) $service->configurator['function']);
            } else {
                if (isset($service->configurator['service'])) {
                    $class = new Reference((string) $service->configurator['service'], ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
                } else {
                    $class = (string) $service->configurator['class'];
                }

                $definition->setConfigurator(array($class, (string) $service->configurator['method']));
            }
        }

        foreach ($service->call as $call) {
            $definition->addMethodCall((string) $call['method'], $this->getArgumentsAsPhp($call, 'argument'));
        }

        foreach ($service->tag as $tag) {
            $parameters = array();
            foreach ($tag->attributes() as $name => $value) {
                if ('name' === $name) {
                    continue;
                }

                $parameters[$name] = XmlUtils::phpize($value);
            }

            $definition->addTag((string) $tag['name'], $parameters);
        }

        return $definition;
    }
457457
private function addService($id, Definition $definition, &$file = null)
    {
        $this->definitionVariables = new \SplObjectStorage();
        $this->referenceVariables = array();
        $this->variableCount = 0;

        $return = array();

        if ($class = $definition->getClass()) {
            $class = $this->container->resolveEnvPlaceholders($class);
            $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\'));
        } elseif ($definition->getFactory()) {
            $factory = $definition->getFactory();
            if (is_string($factory)) {
                $return[] = sprintf('@return object An instance returned by %s()', $factory);
            } elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
                if (is_string($factory[0]) || $factory[0] instanceof Reference) {
                    $return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]);
                } elseif ($factory[0] instanceof Definition) {
                    $return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]);
                }
            }
        }

        if ($definition->isDeprecated()) {
            if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
                $return[] = '';
            }

            $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id));
        }

        $return = str_replace("\n     * \n", "\n     *\n", implode("\n     * ", $return));
        $return = $this->container->resolveEnvPlaceholders($return);

        $shared = $definition->isShared() ? ' shared' : '';
        $public = $definition->isPublic() ? 'public' : 'private';
        $autowired = $definition->isAutowired() ? ' autowired' : '';

        if ($definition->isLazy()) {
            $lazyInitialization = '$lazyLoad = true';
        } else {
            $lazyInitialization = '';
        }

        $asFile = $this->asFiles && $definition->isShared() && !$this->isHotPath($definition);
        $methodName = $this->generateMethodName($id);
        if ($asFile) {
            $file = $methodName.'.php';
            $code = "        // Returns the $public '$id'$shared$autowired service.\n\n";
        } else {
            $code = <<<EOF

    /*{$this->docStar}
     * Gets the $public '$id'$shared$autowired service.
     *
     * $return
     */
    protected function {$methodName}($lazyInitialization)
    {

EOF;
        }

        if ($this->getProxyDumper()->isProxyCandidate($definition)) {
            $factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)';
            $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName));
        }

        if ($definition->isDeprecated()) {
            $code .= sprintf("        @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
        }

        $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition));
        $constructorDefinitions = $this->getDefinitionsFromArguments(array($definition->getArguments(), $definition->getFactory()));
        $otherDefinitions = new \SplObjectStorage();

        foreach ($inlinedDefinitions as $def) {
            if ($def === $definition || isset($constructorDefinitions[$def])) {
                $constructorDefinitions[$def] = $inlinedDefinitions[$def];
            } else {
                $otherDefinitions[$def] = $inlinedDefinitions[$def];
            }
        }

        $isSimpleInstance = !$definition->getProperties() && !$definition->getMethodCalls() && !$definition->getConfigurator();

        $code .=
            $this->addServiceInclude($id, $definition, $inlinedDefinitions).
            $this->addServiceLocalTempVariables($id, $definition, $constructorDefinitions, $inlinedDefinitions).
            $this->addServiceInlinedDefinitions($id, $definition, $constructorDefinitions, $isSimpleInstance).
            $this->addServiceInstance($id, $definition, $isSimpleInstance).
            $this->addServiceLocalTempVariables($id, $definition, $otherDefinitions, $inlinedDefinitions).
            $this->addServiceInlinedDefinitions($id, $definition, $otherDefinitions, $isSimpleInstance).
            $this->addServiceInlinedDefinitionsSetup($id, $definition, $inlinedDefinitions, $isSimpleInstance).
            $this->addServiceProperties($definition).
            $this->addServiceMethodCalls($definition).
            $this->addServiceConfigurator($definition).
            (!$isSimpleInstance ? "\n        return \$instance;\n" : '')
        ;

        if ($asFile) {
            $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code)));
        } else {
            $code .= "    }\n";
        }

        $this->definitionVariables = null;
        $this->referenceVariables = null;

        return $code;
    }
1043673
public function getDefinition($id)
    {
        $id = $this->normalizeId($id);

        if (!isset($this->definitions[$id])) {
            throw new ServiceNotFoundException($id);
        }

        return $this->definitions[$id];
    }
307087
public function getServiceById($id)
    {
        if ($name = $this->getServiceNameById($id)) {
            return $this->getService($name);
        }

        return null;
    }
494201
public function set($name, $definition, $shared = false)
    {
        /** @var $widget \Phalcon\DI\Service */
        $widget = $this->getDI()->get('\Phalcon\DI\Service', [$name, $definition, $shared]);
        $this->_widgets[$name] = $widget;

        return $this;
    }
971877
private function addService($id, Definition $definition)
    {
        $this->definitionVariables = new \SplObjectStorage();
        $this->referenceVariables = array();
        $this->variableCount = 0;

        $return = array();

        if ($definition->isSynthetic()) {
            $return[] = '@throws RuntimeException always since this service is expected to be injected dynamically';
        } elseif ($class = $definition->getClass()) {
            $class = $this->container->resolveEnvPlaceholders($class);
            $return[] = sprintf('@return %s A %s instance', 0 === strpos($class, '%') ? 'object' : '\\'.ltrim($class, '\\'), ltrim($class, '\\'));
        } elseif ($definition->getFactory()) {
            $factory = $definition->getFactory();
            if (is_string($factory)) {
                $return[] = sprintf('@return object An instance returned by %s()', $factory);
            } elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
                if (is_string($factory[0]) || $factory[0] instanceof Reference) {
                    $return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]);
                } elseif ($factory[0] instanceof Definition) {
                    $return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]);
                }
            }
        }

        if ($definition->isDeprecated()) {
            if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
                $return[] = '';
            }

            $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id));
        }

        $return = str_replace("\n     * \n", "\n     *\n", implode("\n     * ", $return));
        $return = $this->container->resolveEnvPlaceholders($return);

        $doc = '';
        if ($definition->isShared()) {
            $doc .= <<<'EOF'

     *
     * This service is shared.
     * This method always returns the same instance of the service.
EOF;
        }

        if (!$definition->isPublic()) {
            $doc .= <<<'EOF'

     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
EOF;
        }

        if ($definition->isAutowired()) {
            $doc = <<<EOF

     *
     * This service is autowired.
EOF;
        }

        if ($definition->isLazy()) {
            $lazyInitialization = '$lazyLoad = true';
            $lazyInitializationDoc = "\n     * @param bool    \$lazyLoad whether to try lazy-loading the service with a proxy\n     *";
        } else {
            $lazyInitialization = '';
            $lazyInitializationDoc = '';
        }

        // with proxies, for 5.3.3 compatibility, the getter must be public to be accessible to the initializer
        $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
        $visibility = $isProxyCandidate ? 'public' : 'protected';
        $methodName = $this->generateMethodName($id);
        $code = <<<EOF

    /*{$this->docStar}
     * Gets the '$id' service.$doc
     *$lazyInitializationDoc
     * $return
     */
    {$visibility} function {$methodName}($lazyInitialization)
    {

EOF;

        $code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $methodName) : '';

        if ($definition->isSynthetic()) {
            $code .= sprintf("        throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n    }\n", $id);
        } else {
            if ($definition->isDeprecated()) {
                $code .= sprintf("        @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
            }

            $code .=
                $this->addServiceInclude($id, $definition).
                $this->addServiceLocalTempVariables($id, $definition).
                $this->addServiceInlinedDefinitions($id, $definition).
                $this->addServiceInstance($id, $definition).
                $this->addServiceInlinedDefinitionsSetup($id, $definition).
                $this->addServiceProperties($id, $definition).
                $this->addServiceMethodCalls($id, $definition).
                $this->addServiceConfigurator($id, $definition).
                $this->addServiceReturn($id, $definition)
            ;
        }

        $this->definitionVariables = null;
        $this->referenceVariables = null;

        return $code;
    }
1337154
public function set($id, $service)
    {
        // Runs the internal initializer; used by the dumped container to include always-needed files
        if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) {
            $initialize = $this->privates['service_container'];
            unset($this->privates['service_container']);
            $initialize();
        }

        if ('service_container' === $id) {
            throw new InvalidArgumentException('You cannot set service "service_container".');
        }

        if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
            if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) {
                // no-op
            } elseif (null === $service) {
                throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot unset it.', $id));
            } else {
                throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot replace it.', $id));
            }
        } elseif (isset($this->services[$id])) {
            throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id));
        }

        if (isset($this->aliases[$id])) {
            unset($this->aliases[$id]);
        }

        if (null === $service) {
            unset($this->services[$id]);

            return;
        }

        $this->services[$id] = $service;
    }
278823
protected function setDefinition($id, $definition, $shared = false)
    {
        $this->definitions[$id] = $definition;
        if (true === $shared) {
            $this->shared[$id] = $id;
        }
    }
637435
public function has($id) {
		if (isset($this->_definitions[$id])) {
			return true;
		}
		
		return $this->getLocatorByServiceId($id) !== null;
	}
1113539
public function supports($id, $definition)
    {
        if (is_null($definition)) {
            $definition = $id;
        }

        return is_string($definition) && class_exists($definition);
    }