/** * 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 FactoryParameterResolver($this->container), new NumericArrayResolver()]); $this->invoker = new Invoker($parameterResolver, $this->container); } try { return $this->invoker->call($definition->getCallable(), [$this->container, $definition]); } catch (NotCallableException $e) { 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())); } }
/** * 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 = []) { $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) { $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())); } }
/** * 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; }
/** * {@inheritdoc} */ public function addDefinition(Definition $definition) { $this->definitions[$definition->getName()] = $definition; }
/** * 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); }
/** * Add a single definition * * @param Definition $definition */ public function addDefinition(Definition $definition) { $this->clearCacheEntry($definition->getName()); $this->source->addDefinition($definition); }
/** * {@inheritdoc} */ public function addDefinition(Definition $definition) { $this->definitions[$definition->getName()] = $definition; // Clear cache $this->wildcardDefinitions = null; }
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))); }