Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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