d93d57c74ad6926670ccb596c590e638da516c38
[GitHub/WoltLab/WCF.git] /
1 <?php
2
3 namespace DI\Definition\Resolver;
4
5 use DI\Definition\Definition;
6 use DI\Definition\Exception\DefinitionException;
7 use DI\Proxy\ProxyFactory;
8 use Interop\Container\ContainerInterface;
9
10 /**
11 * Dispatches to more specific resolvers.
12 *
13 * Dynamic dispatch pattern.
14 *
15 * @since 5.0
16 * @author Matthieu Napoli <matthieu@mnapoli.fr>
17 */
18 class ResolverDispatcher implements DefinitionResolver
19 {
20 /**
21 * @var ContainerInterface
22 */
23 private $container;
24
25 /**
26 * @var ProxyFactory
27 */
28 private $proxyFactory;
29
30 private $valueResolver;
31 private $arrayResolver;
32 private $factoryResolver;
33 private $decoratorResolver;
34 private $aliasResolver;
35 private $objectResolver;
36 private $instanceResolver;
37 private $envVariableResolver;
38 private $stringResolver;
39
40 public function __construct(ContainerInterface $container, ProxyFactory $proxyFactory)
41 {
42 $this->container = $container;
43 $this->proxyFactory = $proxyFactory;
44 }
45
46 /**
47 * Resolve a definition to a value.
48 *
49 * @param Definition $definition Object that defines how the value should be obtained.
50 * @param array $parameters Optional parameters to use to build the entry.
51 *
52 * @throws DefinitionException If the definition cannot be resolved.
53 *
54 * @return mixed Value obtained from the definition.
55 */
56 public function resolve(Definition $definition, array $parameters = [])
57 {
58 $definitionResolver = $this->getDefinitionResolver($definition);
59
60 return $definitionResolver->resolve($definition, $parameters);
61 }
62
63 /**
64 * Check if a definition can be resolved.
65 *
66 * @param Definition $definition Object that defines how the value should be obtained.
67 * @param array $parameters Optional parameters to use to build the entry.
68 *
69 * @return bool
70 */
71 public function isResolvable(Definition $definition, array $parameters = [])
72 {
73 $definitionResolver = $this->getDefinitionResolver($definition);
74
75 return $definitionResolver->isResolvable($definition, $parameters);
76 }
77
78 /**
79 * Returns a resolver capable of handling the given definition.
80 *
81 * @param Definition $definition
82 *
83 * @throws \RuntimeException No definition resolver was found for this type of definition.
84 * @return DefinitionResolver
85 */
86 private function getDefinitionResolver(Definition $definition)
87 {
88 switch (true) {
89 case ($definition instanceof \DI\Definition\ObjectDefinition):
90 if (! $this->objectResolver) {
91 $this->objectResolver = new ObjectCreator($this, $this->proxyFactory);
92 }
93 return $this->objectResolver;
94 case ($definition instanceof \DI\Definition\ValueDefinition):
95 if (! $this->valueResolver) {
96 $this->valueResolver = new ValueResolver();
97 }
98 return $this->valueResolver;
99 case ($definition instanceof \DI\Definition\AliasDefinition):
100 if (! $this->aliasResolver) {
101 $this->aliasResolver = new AliasResolver($this->container);
102 }
103 return $this->aliasResolver;
104 case ($definition instanceof \DI\Definition\DecoratorDefinition):
105 if (! $this->decoratorResolver) {
106 $this->decoratorResolver = new DecoratorResolver($this->container, $this);
107 }
108 return $this->decoratorResolver;
109 case ($definition instanceof \DI\Definition\FactoryDefinition):
110 if (! $this->factoryResolver) {
111 $this->factoryResolver = new FactoryResolver($this->container);
112 }
113 return $this->factoryResolver;
114 case ($definition instanceof \DI\Definition\ArrayDefinition):
115 if (! $this->arrayResolver) {
116 $this->arrayResolver = new ArrayResolver($this);
117 }
118 return $this->arrayResolver;
119 case ($definition instanceof \DI\Definition\EnvironmentVariableDefinition):
120 if (! $this->envVariableResolver) {
121 $this->envVariableResolver = new EnvironmentVariableResolver($this);
122 }
123 return $this->envVariableResolver;
124 case ($definition instanceof \DI\Definition\StringDefinition):
125 if (! $this->stringResolver) {
126 $this->stringResolver = new StringResolver($this->container);
127 }
128 return $this->stringResolver;
129 case ($definition instanceof \DI\Definition\InstanceDefinition):
130 if (! $this->instanceResolver) {
131 $this->instanceResolver = new InstanceInjector($this, $this->proxyFactory);
132 }
133 return $this->instanceResolver;
134 default:
135 throw new \RuntimeException('No definition resolver was configured for definition of type ' . get_class($definition));
136 }
137 }
138 }