/** * Injects dependencies on an existing instance. * * @param InstanceDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { try { $this->injectMethodsAndProperties($definition->getInstance(), $definition->getObjectDefinition()); } catch (NotFoundException $e) { $message = sprintf('Error while injecting dependencies into %s: %s', get_class($definition->getInstance()), $e->getMessage()); throw new DependencyException($message, 0, $e); } }
/** * Resolve an array definition to a value. * * An array definition can contain simple values or references to other entries. * * @param ArrayDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $values = $definition->getValues(); // Resolve nested definitions foreach ($values as $key => $value) { if ($value instanceof DefinitionHelper) { $values[$key] = $this->resolveDefinition($value, $definition, $key); } } return $values; }
/** * Resolve a factory definition to a value. * * This will call the callable of the definition. * * @param FactoryDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $callable = $definition->getCallable(); if (!is_callable($callable)) { throw new DefinitionException(sprintf('The factory definition "%s" is not callable', $definition->getName())); } if (!$this->invoker) { $this->invoker = new Invoker(new NumericArrayResolver(), $this->container); } return $this->invoker->call($callable, [$this->container]); }
/** * Resolve a factory definition to a value. * * This will call the callable of the definition. * * @param FactoryDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { if (!$this->invoker) { $this->invoker = new Invoker(new NumericArrayResolver(), $this->container); } try { return $this->invoker->call($definition->getCallable(), [$this->container]); } catch (NotCallableException $e) { throw new DefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s', $definition->getName(), $e->getMessage())); } }
/** * Resolve a value definition to a value. * * A value definition is simple, so this will just return the value of the ValueDefinition. * * @param StringDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $expression = $definition->getExpression(); $result = preg_replace_callback('#\\{([^\\{\\}]+)\\}#', function (array $matches) use($definition) { try { return $this->container->get($matches[1]); } catch (NotFoundException $e) { throw new DependencyException(sprintf("Error while parsing string expression for entry '%s': %s", $definition->getName(), $e->getMessage()), 0, $e); } }, $expression); if ($result === null) { throw new \RuntimeException(sprintf('An unknown error occurred while parsing the string definition: \'%s\'', $expression)); } return $result; }
/** * Resolve an environment variable definition to a value. * * @param EnvironmentVariableDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $value = call_user_func($this->variableReader, $definition->getVariableName()); if (false !== $value) { return $value; } if (!$definition->isOptional()) { throw new DefinitionException(sprintf("The environment variable '%s' has not been defined", $definition->getVariableName())); } $value = $definition->getDefaultValue(); // Nested definition if ($value instanceof DefinitionHelper) { return $this->definitionResolver->resolve($value->getDefinition('')); } return $value; }
/** * Resolve a decorator definition to a value. * * This will call the callable of the definition and pass it the decorated entry. * * @param DecoratorDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $callable = $definition->getCallable(); if (!is_callable($callable)) { throw new DefinitionException(sprintf('The decorator "%s" is not callable', $definition->getName())); } $decoratedDefinition = $definition->getDecoratedDefinition(); if (!$decoratedDefinition instanceof Definition) { if (!$definition->getSubDefinitionName()) { throw new DefinitionException('Decorators cannot be nested in another definition'); } throw new DefinitionException(sprintf('Entry "%s" decorates nothing: no previous definition with the same name was found', $definition->getName())); } $decorated = $this->definitionResolver->resolve($decoratedDefinition); return call_user_func($callable, $decorated, $this->container); }
/** * Resolve a factory definition to a value. * * This will call the callable of the definition. * * @param FactoryDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { if (!$this->invoker) { $parameterResolver = new ResolverChain([new AssociativeArrayResolver(), new FactoryParameterResolver($this->container), new NumericArrayResolver()]); $this->invoker = new Invoker($parameterResolver, $this->container); } $callable = $definition->getCallable(); try { $providedParams = [$this->container, $definition]; $extraParams = $this->resolveExtraParams($definition->getParameters()); $providedParams = array_merge($providedParams, $extraParams); return $this->invoker->call($callable, $providedParams); } catch (NotCallableException $e) { // Custom error message to help debugging if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) { throw new DefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s. Invokable classes cannot be automatically resolved if autowiring is disabled on the container, you need to enable autowiring or define the entry manually.', $definition->getName(), $e->getMessage())); } throw new DefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s', $definition->getName(), $e->getMessage())); } catch (NotEnoughParametersException $e) { throw new DefinitionException(sprintf('Entry "%s" cannot be resolved: %s', $definition->getName(), $e->getMessage())); } }
/** * @param SelfResolvingDefinition $definition * * {@inheritdoc} */ public function isResolvable(Definition $definition, array $parameters = []) { return $definition->isResolvable($this->container); }
/** * @param AliasDefinition $definition * * {@inheritdoc} */ public function isResolvable(Definition $definition, array $parameters = []) { return $this->container->has($definition->getTargetEntryName()); }
/** * Resolves a definition. * * Checks for circular dependencies while resolving the definition. * * @param Definition $definition * @param array $parameters * * @throws DependencyException Error while resolving the entry. * @return mixed */ private function resolveDefinition(Definition $definition, array $parameters = []) { $entryName = $definition->getName(); // Check if we are already getting this entry -> circular dependency if (isset($this->entriesBeingResolved[$entryName])) { throw new DependencyException("Circular dependency detected while trying to resolve entry '{$entryName}'"); } $this->entriesBeingResolved[$entryName] = true; // Resolve the definition try { $value = $this->definitionResolver->resolve($definition, $parameters); } catch (Exception $exception) { unset($this->entriesBeingResolved[$entryName]); throw $exception; } unset($this->entriesBeingResolved[$entryName]); return $value; }
/** * {@inheritdoc} */ public function setSubDefinition(Definition $definition) { if (!$definition instanceof ObjectDefinition) { throw new DefinitionException(sprintf("Container entry '%s' extends entry '%s' which is not an object", $this->getName(), $definition->getName())); } // The current prevails if ($this->className === null) { $this->className = $definition->className; } if ($this->scope === null) { $this->scope = $definition->scope; } if ($this->lazy === null) { $this->lazy = $definition->lazy; } // Merge constructor injection $this->mergeConstructorInjection($definition); // Merge property injections $this->mergePropertyInjections($definition); // Merge method injections $this->mergeMethodInjections($definition); }
/** * Resolve an array definition to a value. * * An array definition can contain simple values or references to other entries. * * @param ArrayDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { $values = $definition->getValues(); $values = $this->resolveNestedDefinitions($definition, $values); return $values; }
/** * Resolve a value definition to a value. * * A value definition is simple, so this will just return the value of the ValueDefinition. * * @param ValueDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = []) { return $definition->getValue(); }
/** * The definition is not resolvable if the class is not instantiable (interface or abstract) * or if the class doesn't exist. * * @param ObjectDefinition $definition * * {@inheritdoc} */ public function isResolvable(Definition $definition, array $parameters = []) { return $definition->isInstantiable(); }
/** * {@inheritdoc} */ public function addDefinition(Definition $definition) { $this->definitions[$definition->getName()] = $definition; }
/** * {@inheritdoc} */ public function addDefinition(Definition $definition) { $this->definitions[$definition->getName()] = $definition; // Clear cache $this->wildcardDefinitions = null; }
/** * Add a single definition * * @param Definition $definition */ public function addDefinition(Definition $definition) { $this->clearCacheEntry($definition->getName()); $this->source->addDefinition($definition); }
public static function create(Definition $definition, $message) { return new self(sprintf("Entry %s cannot be resolved: %s\nDefinition of %s:\n%s", $definition->getName(), $message, $definition->getName(), Debug::dump($definition))); }