Completed
Push — master ( e9d1ee...cb5c09 )
by Théo
06:38
created

ServicesBuilder::getParameterResolver()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 9
ccs 3
cts 5
cp 0.6
rs 9.6666
c 1
b 0
f 1
cc 2
eloc 5
nc 2
nop 1
crap 2.2559
1
<?php
2
3
/*
4
 * This file is part of the LaravelYaml package.
5
 *
6
 * (c) Théo FIDRY <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Fidry\LaravelYaml\DependencyInjection\Builder;
13
14
use Fidry\LaravelYaml\DependencyInjection\Builder\Instantiator\ServiceInstantiator;
15
use Fidry\LaravelYaml\DependencyInjection\Definition\DecorationInterface;
16
use Fidry\LaravelYaml\DependencyInjection\Definition\ServiceInterface;
17
use Fidry\LaravelYaml\DependencyInjection\Resolver\BaseReferenceResolver;
18
use Fidry\LaravelYaml\DependencyInjection\Resolver\BuiltParameterResolver;
19
use Fidry\LaravelYaml\DependencyInjection\Resolver\ParameterResolverInterface;
20
use Fidry\LaravelYaml\DependencyInjection\Resolver\ReferenceResolverInterface;
21
use Fidry\LaravelYaml\Exception\DependencyInjection\Exception;
22
use Fidry\LaravelYaml\Exception\DependencyInjection\Resolver\Exception as ResolverException;
23
use Illuminate\Contracts\Config\Repository as ConfigRepository;
24
use Illuminate\Contracts\Container\BindingResolutionException;
25
use Illuminate\Contracts\Foundation\Application;
26
27
/**
28
 * @author Théo FIDRY <[email protected]>
29
 */
30
final class ServicesBuilder implements BuilderInterface
31
{
32
    /**
33
     * @var array
34
     */
35
    private $parameters;
36
37
    /**
38
     * @var ReferenceResolverInterface
39
     */
40
    private $referenceResolver;
41
42
    /**
43
     * @var ServiceInterface[]
44
     */
45
    private $services;
46
47
    /**
48
     * @var ParameterResolverInterface|null
49
     */
50
    private $parameterResolver;
51
52
    /**
53
     * @param ServiceInterface[]              $services
54
     * @param array                           $parameters
55
     * @param ParameterResolverInterface|null $parameterResolver
56
     * @param ReferenceResolverInterface|null $referenceResolver
57
     */
58 24
    public function __construct(
59
        array $services,
60
        array $parameters,
61
        ParameterResolverInterface $parameterResolver = null,
62
        ReferenceResolverInterface $referenceResolver = null
63
    ) {
64 24
        $this->services = $services;
65 24
        $this->parameters = $parameters;
66 24
        $this->parameterResolver = $parameterResolver;
67 24
        $this->referenceResolver = (null === $referenceResolver) ? new BaseReferenceResolver() : $referenceResolver;
68 24
    }
69
70 24
    public function build(Application $application)
71
    {
72
        try {
73 24
            $parameterResolver = $this->getParameterResolver($application);
74 24
            $instantiator = new ServiceInstantiator($parameterResolver, $this->referenceResolver, $application);
75 24
            foreach ($this->services as $service) {
76 21
                $this->buildService($service, $instantiator, $application);
77 5
            }
78
79 15
            return $this->parameters;
80 9
        } catch (BindingResolutionException $exception) {
81 3
            throw new Exception(sprintf('Could not load "%s" class', ConfigRepository::class), 0, $exception);
82 6
        } catch (ResolverException $exception) {
83
            throw new Exception('Could not resolve the parameters', 0, $exception);
84 6
        } catch (\Exception $exception) {
85 6
            throw new Exception('Could not build the parameters', 0, $exception);
86
        }
87
    }
88
89
    /**
90
     * @param Application $application
91
     *
92
     * @return ParameterResolverInterface
93
     */
94 24
    private function getParameterResolver(Application $application)
95
    {
96 24
        if (null !== $this->parameterResolver) {
97 24
            return $this->parameterResolver;
98
        }
99
        $config = $application->make(ConfigRepository::class);
100
101
        return new BuiltParameterResolver($this->parameters, $config);
102
    }
103
104 21
    private function buildService(
105
        ServiceInterface $service,
106
        ServiceInstantiator $instantiator,
107
        Application $application
108
    ) {
109 21
        $serviceId = ($service instanceof DecorationInterface) ? $service->getDecoration()[0] : $service->getName();
110 21
        $application->singleton(
111 7
            $serviceId,
112 14
            function () use ($instantiator, $service) {
113
                return $instantiator->create($service);
114 14
            }
115 7
        );
116 15
        $application->bind($service->getClass(), $service->getName());
117 12
        $this->bindAutowiringTypes($service, $application);
118 12
        $this->tagService($service, $application);
119 12
    }
120
121 12
    private function bindAutowiringTypes(ServiceInterface $service, Application $application)
122
    {
123 12
        foreach ($service->getAutowiringTypes() as $binding) {
124 3
            $application->bind($binding, $service->getName());
125 4
        }
126 12
    }
127
128 12
    private function tagService(ServiceInterface $service, Application $application)
129
    {
130 12
        if (count($service->getTags()) !== 0) {
131 3
            $application->tag($service->getName(), array_keys($service->getTags()));
132 1
        }
133 12
    }
134
}
135