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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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;
}
doc_Drupal
2025-01-10 15:47:30
Comments
Leave a Comment

Please login to continue.