Resolves a definition.

Checks for circular dependencies while resolving the definition.

@param DefinitionInterface $definition
@param array               $parameters

@throws DependencyException Error while resolving the entry.
@return mixed
777573
protected function _resolveDefinition(
        DefinitionInterface $definition, array $parameters = [])
    {
        $entryName = $definition->getName();
        $definitionResolver = $this->_getDefinitionResolver($definition);

        try {
            $value = $definitionResolver->resolve($definition, $parameters);
        } catch (\Exception $exception) {
            throw new DependencyException(
                "An error occurred while resolving " .
                "entry '{$entryName}': " . $exception->getMessage(),
                0,
                $exception
            );
        }

        return $value;
    }
953620
protected function resolveDependencies( array $dependencies, array $parameters ) {

		$args = [];

		foreach ( $dependencies as $dependency ) {

			// If a dependency is set via the parameters passed in, use it.
			if ( isset( $parameters[ $dependency->getName() ] ) ) {

				$args[] = $parameters[ $dependency->getName() ];

			// If the parameter is a class, resolve it.
			} elseif ( ! is_null( $dependency->getClass() ) ) {

				$args[] = $this->resolve( $dependency->getClass()->getName() );

			// Else, use the default parameter value.
			} elseif ( $dependency->isDefaultValueAvailable() ) {

				$args[] = $dependency->getDefaultValue();
			}
		}

		return $args;
	}
369826
protected function transformDependency(ReflectionParameter $parameter, $parameters)
    {
        if (is_null($class = $parameter->getClass())) {
            return;
        }

        // The parameter references a class.
        else if (! $class->isSubclassOf(Model::class)) {
            return $this->container->make($class->name);
        }

        $identifier = Arr::first($parameters, function ($parameterKey) use ($parameter)
        {
            return $parameterKey === $parameter->name;
        });

        if (! is_null($identifier)) {
            $instance = $class->newInstance();

            return call_user_func(array($instance, 'find'), $identifier);
        }
    }
369587
public function define( $alias, $definition ) {
		if ( is_array( $alias ) ) {
			$class = current( $alias );
			$alias = key( $alias );
		}

		if ( isset( $this->aliases[ $alias ] ) ) {
			throw new DefinedAliasException( $alias );
		}

		$this->aliases[ $alias ]     = true;
		$this->definitions[ $alias ] = $definition;

		// Closures are treated as factories unless
		// defined via Container::share.
		if ( ! $definition instanceof \Closure ) {
			$this->shared[ $alias ] = true;
		}

		if ( isset( $class ) ) {
			$this->classes[ $class ] = $alias;
		}

		return $this;
	}
615289
protected function resolveInterfaceExtension(InterfaceDefinition $definition, Endpoint $endpoint): void
    {
        $bundleNamespace = ClassUtils::relatedBundleNamespace($definition->getClass());
        $extensionClass = ClassUtils::applyNamingConvention($bundleNamespace, 'Extension', null, $definition->getName().'Extension');
        if (class_exists($extensionClass)) {
            foreach ($definition->getImplementors() as $implementor) {
                $definition->addExtension($extensionClass);
                $object = $endpoint->getType($implementor);
                if ($object instanceof HasExtensionsInterface) {
                    $object->addExtension($extensionClass);
                }
            }
        }
    }
1123646
private function resolvePrimitiveParameter(\ReflectionParameter $dependency)
    {
        if ($dependency->isDefaultValueAvailable()) {
            return $dependency->getDefaultValue();
        }

        $class         = $dependency->getDeclaringClass()->getName();
        $method        = $dependency->getDeclaringFunction()->getName();
        $parameterName = $dependency->getName();

        throw new \OutOfBoundsException("Parameter {$parameterName} is not supplied for {$class}::{$method}.");
    }
192646
private function getDictionaryBuilder(DictionaryDefinition $definition): DictionaryBuilderInterface
    {
        if (!$this->dictionaryBuilders->has($typeName = $definition->getType())) {
            $typeName = 'default';
        }

        return $this->dictionaryBuilders->get($typeName);
    }
357393
protected static function addDependencyForCallParameter($container, $parameter,
                                                            array &$parameters, &$dependencies)
    {
        if (array_key_exists($parameter->name, $parameters)) {
            $dependencies[] = $parameters[$parameter->name];

            unset($parameters[$parameter->name]);
        } elseif ($parameter->getClass() && array_key_exists($parameter->getClass()->name, $parameters)) {
            $dependencies[] = $parameters[$parameter->getClass()->name];

            unset($parameters[$parameter->getClass()->name]);
        } elseif ($parameter->getClass()) {
            $dependencies[] = $container->make($parameter->getClass()->name);
        } elseif ($parameter->isDefaultValueAvailable()) {
            $dependencies[] = $parameter->getDefaultValue();
        }
    }
942082
public function resolveCallable(?string $name, callable $closure, ?array $parameters = null)
    {
        $definitions = isset($name) && $this->container->isDefined($name)
            ? $this->container->getDefiniition($name) : null;

        $callable = $this->getCallable($closure);
        $parameters = $parameters ?? $this->resolveParameters($callable->getParameters() ?? null, $definitions);

        return $callable->invokeArgs($parameters);
    }
148460
public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
    {
        $instanceCount = 0;

        $values = array_values($parameters);

        foreach ($reflector->getParameters() as $key => $parameter) {
            $instance = $this->transformDependency($parameter, $parameters);

            if (! is_null($instance)) {
                $instanceCount++;

                $this->spliceIntoParameters($parameters, $key, $instance);
            }

            // If the parameter is not defined and it have a default value.
            else if (! isset($values[$key - $instanceCount]) && $parameter->isDefaultValueAvailable()) {
                $this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue());
            }
        }

        return $parameters;
    }
317608
protected function _injectMethodsAndProperties(
        DefinitionInterface $definition, $instance)
    {
        $classReflection = new ReflectionClass($instance);

        /** @var ObjectDefinition $definition */

        // Property injections
        foreach ($definition->getProperties() as $property)
        {
            $this->_propertyInjection($instance, $property, $classReflection);
        }

        // Method injections
        foreach ($definition->getMethods() as $method) {
            $this->_methodInjection($instance, $method, $classReflection);
        }
    }
754122
private function isDefinitionShared(Definition $definition)
    {
        if (method_exists($definition, 'isShared')) {
            return $definition->isShared();
        } else if (method_exists($definition, 'getScope')) {
            return $definition->getScope() !== ContainerBuilder::SCOPE_PROTOTYPE;
        }

        return false;
    }
446090
private function hydrateDefinitionArguments(Definition $definition, array &$definitionArray)
    {
        foreach ($definition->getArguments() as $arg) {
            $definitionArray['arguments'][] = $this->convertArgument($arg);
        }
    }
363294
protected function _service($name, $definition, $params)
    {
        if ($definition instanceof Closure) {
            $type = 'singleton';
            $definition = call_user_func_array($definition, $params);
            $this->_definitions[$name] = compact('definition', 'type');
        }
        return $definition;
    }
418223
public static function getDependencies( array $parameters, array $primitives = [], $classAndMethod = null )
	{
		$dependencies = [];

		if ( !array_key_exists( 'fw', $primitives ) )
			$primitives['fw'] = Framework::fw();

		foreach ( $parameters as $parameter )
		{
			try
			{
				/*
				 * If the class is null, it means the dependency is a string or some other
				 * primitive type which we can not resolve since it is not a class and
				 * we will just bomb out with an error since we have no-where to go.
				 */
				if ( array_key_exists( $parameter->name, $primitives ) )
					$dependencies[] = $primitives[$parameter->name];
				else if ( is_null( $parameter->getClass() ) )
					$dependencies[] = static::resolve( $parameter->name );
				else
				{
					$depend = static::resolveClass( $parameter->getClass()->name );
					if ( is_null( $depend ) )
						throw new BindingException();
					if ( is_array( $depend ) )
					{
						if ( array_key_exists( $parameter->name, $depend ) )
							$depend = $depend[$parameter->name];
						else
							$depend = $depend[0];
					}
					$dependencies[] = $depend;
				}
			}
			catch ( BindingException $e )
			{
				/*
				 * If we can not resolve the class instance, we will check to see if the value
				 * is optional, and if it is we will return the optional parameter value as
				 * the value of the dependency, similarly to how we do this with scalars.
				 */
				if ( $parameter->isDefaultValueAvailable() )
					$dependencies[] = $parameter->getDefaultValue();
				else if ( $parameter->isOptional() )
					$dependencies[] = null;
				else
				{
					$parameterClass = $parameter->getClass()->name;
					foreach ( $primitives as $prim )
						if ( $prim instanceof $parameterClass )
						{
							$dependencies[] = $prim;
							continue;
						}

					$params = [];
					foreach ( $parameters as $param )
						$params[] = ( !is_null( $param->getClass() ) ? $param->getClass()->getName() . " " : "" ) . ( $param->isPassedByReference() ? "&" : "" ) . "$" . $param->getName() . ( $param->isDefaultValueAvailable() ? " = " . ( is_array( $param->getDefaultValue() ) ? "[" . implode( ', ', $param->getDefaultValue() ) . "]" : $param->getDefaultValue() ) : ( $param->isOptional() ? " = null" : "" ) );
					throw new BindingException( "Dependency injection failed for " . $parameter . " on " . $classAndMethod . "( " . implode( ', ', $params ) . " )" );
				}
			}
		}

		return $dependencies;
	}
859419
protected function loadDependency($name, $dependencyDefinition, &$loadedDependencies = array()){
        $newInstance= NULL;
        //Si es singleton analiza si existe y si puede devuelve la msima
        if(isset($this->singletons[$name])){
            $newInstance= $this->singletons[$name];
        }else{            
            //Veo si tiene namespace y si tiene le agrego el mismo
            $namespace= (isset($dependencyDefinition['namespace']) ? $dependencyDefinition['namespace'] : ''); 
            $dir= explode("/", $dependencyDefinition['class']);
            $class= $dir[count($dir) - 1];
            if($namespace != ''){ $class= "\\" . $namespace . "\\" . $class;}
            
            $newInstance= NULL;
            if(isset($dependencyDefinition['factory-method'])){
                $factoryMethod= $dependencyDefinition['factory-method'];
                if(isset($dependencyDefinition['factory-bean'])){
                    $factoryBean= $this->getDependency($dependencyDefinition['factory-bean'], $loadedDependencies);
                    $newInstance= $factoryBean->$factoryMethod();
                }else{
                    $newInstance= $class::$factoryMethod();
                }
            }else{
                //Consigo los parametros del constructor
                $params= array();
                if(isset($dependencyDefinition['construct'])){
                    //Parseo los parametros correctamente
                    $params= $this->parseProperties($dependencyDefinition['construct']);
                }
                //Creo una instancia con el constructor correspondiente en base a los parametros
                $reflection= new \ReflectionClass($class);
                $newInstance= $reflection->newInstanceArgs($params);
                //La agrego a loadedDependencies para dependencias circulares
                $loadedDependencies[$name]= $newInstance;
            }
            
            //Si es un singleton la guardo como tal
            if(isset($dependencyDefinition['singleton']) && ($dependencyDefinition['singleton'] == "TRUE" || $dependencyDefinition['singleton'] == "true")){
                $this->singletons[$name]= $newInstance;
            }

            //Injecto las dependencias a las propiedades
            //Primero veo si hay Referencia a otras dependencias y cargo las mismas y luego guardo las propiedades
            if(isset($dependencyDefinition['properties'])){
                $properties= $this->parseProperties($dependencyDefinition['properties'], $loadedDependencies);
                $reflection= new Reflection($newInstance);
                $reflection->setProperties($properties, TRUE);
            }                       
        }        
        return $newInstance;
    }
1215645
protected function _getDefinitionResolver(DefinitionInterface $definition)
    {
        $definitionType = get_class($definition);

        if (! isset($this->_definitionResolvers[$definitionType])) {
            throw new NotFoundException(
                "No definition resolver was configured for definition " .
                "of type $definitionType"
            );
        }

        return $this->_definitionResolvers[$definitionType];
    }