W3cubDocs

/Drupal 8

protected function Container::createService

protected Container::createService(array $definition, $id)

Creates a service from a service definition.

Parameters

array $definition: The service definition to create a service from.

string $id: The service identifier, necessary so it can be shared if its public.

Return value

object The service described by the service definition.

Throws

\Symfony\Component\DependencyInjection\Exception\RuntimeException Thrown when the service is a synthetic service.

\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException Thrown when the configurator callable in $definition['configurator'] is not actually a callable.

\ReflectionException Thrown when the service class takes more than 10 parameters to construct, and cannot be instantiated.

File

core/lib/Drupal/Component/DependencyInjection/Container.php, line 226

Class

Container
Provides a container optimized for Drupal's needs.

Namespace

Drupal\Component\DependencyInjection

Code

protected function createService(array $definition, $id) {
  if (isset($definition['synthetic']) && $definition['synthetic'] === TRUE) {
    throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The service container does not know how to construct this service. The service will need to be set before it is first used.', $id));
  }

  $arguments = array();
  if (isset($definition['arguments'])) {
    $arguments = $definition['arguments'];

    if ($arguments instanceof \stdClass) {
      $arguments = $this->resolveServicesAndParameters($arguments);
    }
  }

  if (isset($definition['file'])) {
    $file = $this->frozen ? $definition['file'] : current($this->resolveServicesAndParameters(array($definition['file'])));
    require_once $file;
  }

  if (isset($definition['factory'])) {
    $factory = $definition['factory'];
    if (is_array($factory)) {
      $factory = $this->resolveServicesAndParameters(array($factory[0], $factory[1]));
    }
    elseif (!is_string($factory)) {
      throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
    }

    $service = call_user_func_array($factory, $arguments);
  }
  else {
    $class = $this->frozen ? $definition['class'] : current($this->resolveServicesAndParameters(array($definition['class'])));
    $length = isset($definition['arguments_count']) ? $definition['arguments_count'] : count($arguments);

    // Optimize class instantiation for services with up to 10 parameters as
    // ReflectionClass is noticeably slow.
    switch ($length) {
      case 0:
        $service = new $class();
        break;

      case 1:
        $service = new $class($arguments[0]);
        break;

      case 2:
        $service = new $class($arguments[0], $arguments[1]);
        break;

      case 3:
        $service = new $class($arguments[0], $arguments[1], $arguments[2]);
        break;

      case 4:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3]);
        break;

      case 5:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
        break;

      case 6:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
        break;

      case 7:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
        break;

      case 8:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
        break;

      case 9:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
        break;

      case 10:
        $service = new $class($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8], $arguments[9]);
        break;

      default:
        $r = new \ReflectionClass($class);
        $service = $r->newInstanceArgs($arguments);
        break;
    }
  }

  // Share the service if it is public.
  if (!isset($definition['public']) || $definition['public'] !== FALSE) {
    // Forward compatibility fix for Symfony 2.8 update.
    if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
      $this->services[$id] = $service;
    }
  }

  if (isset($definition['calls'])) {
    foreach ($definition['calls'] as $call) {
      $method = $call[0];
      $arguments = array();
      if (!empty($call[1])) {
        $arguments = $call[1];
        if ($arguments instanceof \stdClass) {
          $arguments = $this->resolveServicesAndParameters($arguments);
        }
      }
      call_user_func_array(array($service, $method), $arguments);
    }
  }

  if (isset($definition['properties'])) {
    if ($definition['properties'] instanceof \stdClass) {
      $definition['properties'] = $this->resolveServicesAndParameters($definition['properties']);
    }
    foreach ($definition['properties'] as $key => $value) {
      $service->{$key} = $value;
    }
  }

  if (isset($definition['configurator'])) {
    $callable = $definition['configurator'];
    if (is_array($callable)) {
      $callable = $this->resolveServicesAndParameters($callable);
    }

    if (!is_callable($callable)) {
      throw new InvalidArgumentException(sprintf('The configurator for class "%s" is not a callable.', get_class($service)));
    }

    call_user_func($callable, $service);
  }

  return $service;
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Component!DependencyInjection!Container.php/function/Container::createService/8.1.x