function ContainerBuilder::createService
Creates a service for a service definition.
Throws
RuntimeException When the factory definition is incomplete
RuntimeException When the service is a synthetic service
InvalidArgumentException When configure callable is not callable
2 calls to ContainerBuilder::createService()
- ContainerBuilder::doGet in vendor/
symfony/ dependency-injection/ ContainerBuilder.php - ContainerBuilder::doResolveServices in vendor/
symfony/ dependency-injection/ ContainerBuilder.php
File
-
vendor/
symfony/ dependency-injection/ ContainerBuilder.php, line 1082
Class
- ContainerBuilder
- ContainerBuilder is a DI container that provides an API to easily describe services.
Namespace
Symfony\Component\DependencyInjectionCode
private function createService(Definition $definition, array &$inlineServices, bool $isConstructorArgument = false, ?string $id = null, bool|object $tryProxy = true) : mixed {
if (null === $id && isset($inlineServices[$h = spl_object_hash($definition)])) {
return $inlineServices[$h];
}
if ($definition instanceof ChildDefinition) {
throw new RuntimeException(\sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
}
if ($definition->isSynthetic()) {
throw new RuntimeException(\sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
}
if ($definition->isDeprecated()) {
$deprecation = $definition->getDeprecation($id);
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
}
$parameterBag = $this->getParameterBag();
$class = $parameterBag->resolveValue($definition->getClass()) ?: ([
'Closure',
'fromCallable',
] === $definition->getFactory() ? 'Closure' : null);
if ([
'Closure',
'fromCallable',
] === $definition->getFactory() && ('Closure' !== $class || $definition->isLazy())) {
$callable = $parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArgument(0)));
if ($callable instanceof Reference || $callable instanceof Definition) {
$callable = [
$callable,
'__invoke',
];
}
if (\is_array($callable) && ($callable[0] instanceof Reference || $callable[0] instanceof Definition && !isset($inlineServices[spl_object_hash($callable[0])]))) {
$initializer = function () use ($callable, &$inlineServices) {
return $this->doResolveServices($callable[0], $inlineServices);
};
$proxy = eval('return ' . LazyClosure::getCode('$initializer', $callable, $definition, $this, $id) . ';');
$this->shareService($definition, $proxy, $id, $inlineServices);
return $proxy;
}
}
if (true === $tryProxy && $definition->isLazy() && [
'Closure',
'fromCallable',
] !== $definition->getFactory() && !($tryProxy = !($proxy = $this->proxyInstantiator ??= new LazyServiceInstantiator()) || $proxy instanceof RealServiceInstantiator)) {
$proxy = $proxy->instantiateProxy($this, (clone $definition)->setClass($class)
->setTags(($definition->hasTag('proxy') ? [
'proxy' => $parameterBag->resolveValue($definition->getTag('proxy')),
] : []) + $definition->getTags()), $id, function ($proxy = false) use ($definition, &$inlineServices, $id) {
return $this->createService($definition, $inlineServices, true, $id, $proxy);
});
$this->shareService($definition, $proxy, $id, $inlineServices);
return $proxy;
}
if (null !== $definition->getFile()) {
require_once $parameterBag->resolveValue($definition->getFile());
}
$arguments = $definition->getArguments();
if (null !== ($factory = $definition->getFactory())) {
if (\is_array($factory)) {
$factory = [
$this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices, $isConstructorArgument),
$factory[1],
];
}
elseif (!\is_string($factory)) {
throw new RuntimeException(\sprintf('Cannot create service "%s" because of invalid factory.', $id));
}
elseif (str_starts_with($factory, '@=')) {
$factory = fn(ServiceLocator $arguments) => $this->getExpressionLanguage()
->evaluate(substr($factory, 2), [
'container' => $this,
'args' => $arguments,
]);
$arguments = [
new ServiceLocatorArgument($arguments),
];
}
}
$arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($arguments)), $inlineServices, $isConstructorArgument);
if (null !== $id && $definition->isShared() && (isset($this->services[$id]) || isset($this->privates[$id])) && (true === $tryProxy || !$definition->isLazy())) {
return $this->services[$id] ?? $this->privates[$id];
}
if (!array_is_list($arguments)) {
$arguments = array_combine(array_map(fn($k) => preg_replace('/^.*\\$/', '', $k), array_keys($arguments)), $arguments);
}
if (null !== $factory) {
$service = $factory(...$arguments);
if (!$definition->isDeprecated() && \is_array($factory) && \is_string($factory[0])) {
$r = new \ReflectionClass($factory[0]);
if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name);
}
}
}
else {
$r = new \ReflectionClass($class);
if (\is_object($tryProxy)) {
if ($r->getConstructor()) {
$tryProxy->__construct(...$arguments);
}
$service = $tryProxy;
}
else {
$service = $r->getConstructor() ? $r->newInstanceArgs($arguments) : $r->newInstance();
}
if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name);
}
}
$lastWitherIndex = null;
foreach ($definition->getMethodCalls() as $k => $call) {
if ($call[2] ?? false) {
$lastWitherIndex = $k;
}
}
if (null === $lastWitherIndex && (true === $tryProxy || !$definition->isLazy())) {
// share only if proxying failed, or if not a proxy, and if no withers are found
$this->shareService($definition, $service, $id, $inlineServices);
}
$properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices);
foreach ($properties as $name => $value) {
$service->{$name} = $value;
}
foreach ($definition->getMethodCalls() as $k => $call) {
$service = $this->callMethod($service, $call, $inlineServices);
if ($lastWitherIndex === $k && (true === $tryProxy || !$definition->isLazy())) {
// share only if proxying failed, or if not a proxy, and this is the last wither
$this->shareService($definition, $service, $id, $inlineServices);
}
}
if ($callable = $definition->getConfigurator()) {
if (\is_array($callable)) {
$callable[0] = $parameterBag->resolveValue($callable[0]);
if ($callable[0] instanceof Reference) {
$callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices);
}
elseif ($callable[0] instanceof Definition) {
$callable[0] = $this->createService($callable[0], $inlineServices);
}
}
if (!\is_callable($callable)) {
throw new InvalidArgumentException(\sprintf('The configure callable for class "%s" is not a callable.', get_debug_type($service)));
}
$callable($service);
}
return $service;
}