Completed
Pull Request — master (#7)
by Théo
13:29 queued 11:14
created

ServicesBuilder::build()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

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