-
Notifications
You must be signed in to change notification settings - Fork 0
/
ContainerBuilder.php
159 lines (142 loc) · 5.81 KB
/
ContainerBuilder.php
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php declare(strict_types=1);
/**
* Copyright 2020 Bastian Schwarz <bastian@codename-php.de>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace de\codenamephp\platform\di;
use de\codenamephp\platform\di\definitionsProvider\dependency\handler\iHandler;
use de\codenamephp\platform\di\definitionsProvider\dependency\MissingDependencyException;
use de\codenamephp\platform\di\definitionsProvider\dependency\Wrapper;
use de\codenamephp\platform\di\definitionsProvider\iDefintionsProvider;
use de\codenamephp\platform\di\definitionsProvider\iMetaProvider;
use InvalidArgumentException;
/**
*
* @author Bastian Schwarz <bastian@codename-php.de>
*/
final class ContainerBuilder implements iContainerBuilder {
/**
* The actual container builder that will be used to create the container and where the definitions are added to
*
* @var \DI\ContainerBuilder
*/
private \DI\ContainerBuilder $containerBuilder;
/**
* Handles the dependencies of providers
*
* @var definitionsProvider\dependency\handler\iHandler
*/
private iHandler $dependencyHandler;
/**
* Sets the container builder or creates one if null was given. Also sets an instance of
* \de\codenamephp\platform\di\definitionsProvider\dependency\handler\DontHandle as default dependency handler
*
* @param \DI\ContainerBuilder|null $containerBuilder The actual container builder that will be used to create the container and where the definitions are added to
*/
public function __construct(\DI\ContainerBuilder $containerBuilder = null) {
$this->setContainerBuilder($containerBuilder ?? new \DI\ContainerBuilder(ContainerBuilder::class));
$this->setDependencyHandler(new definitionsProvider\dependency\handler\DontHandle());
}
/**
* @return \DI\ContainerBuilder
*/
public function getContainerBuilder() : \DI\ContainerBuilder {
return $this->containerBuilder;
}
/**
* @param \DI\ContainerBuilder $containerBuilder
* @return iContainerBuilder
*/
public function setContainerBuilder(\DI\ContainerBuilder $containerBuilder) : iContainerBuilder {
$this->containerBuilder = $containerBuilder;
return $this;
}
/**
*
* @return definitionsProvider\dependency\handler\iHandler
*/
public function getDependencyHandler() : iHandler {
return $this->dependencyHandler;
}
/**
*
* @param iHandler $dependencyHandler
*
* @return iContainerBuilder
*/
public function setDependencyHandler(definitionsProvider\dependency\handler\iHandler $dependencyHandler) : iContainerBuilder {
$this->dependencyHandler = $dependencyHandler;
return $this;
}
/**
* Adds definitions by a provider class. The provider must implement one of the definitionsProvider\* interfaces and the configuration will be added
* accordingly to the container builder.
*
* Also the dependencies are checked here using the iHandler. If the provider implements the iDependency interface, it is used directly for the dependency
* check. If not, it is wrapper in the Wrapper dependency which is then used.
*
* @param iDefintionsProvider $provider The provider whose definitions will be added, depending on the implemented interfaces
* @return iContainerBuilder
* @throws MissingDependencyException if a dependency that the given provider relies on is missing (from dependencyHandler)
* @throws InvalidArgumentException
*/
public function addDefinitionsByProvider(definitionsProvider\iDefintionsProvider $provider) : iContainerBuilder {
$this->getDependencyHandler()->handle($provider instanceof definitionsProvider\dependency\iDependency ? $provider : new Wrapper($provider));
if($provider instanceof definitionsProvider\iFiles) {
foreach($provider->getFiles() as $file) {
$this->getContainerBuilder()->addDefinitions($file);
}
}
if($provider instanceof definitionsProvider\iArray) {
$this->getContainerBuilder()->addDefinitions($provider->getDefinitions());
}
if($provider instanceof definitionsProvider\iGlobPaths) {
foreach($provider->getGlobPaths() as $globPath) {
$this->addGlobPath($globPath);
}
}
if($provider instanceof iMetaProvider) {
foreach($provider->getProviders() as $metaProvider) {
$this->addDefinitionsByProvider($metaProvider);
}
}
return $this;
}
/**
* Discovers all files found from glob and adds them to the wrapped container builder
*
* @param string $globPath A glob path that will be used to discover definition files
* @return iContainerBuilder
* @throws InvalidArgumentException
*/
public function addGlobPath($globPath) : iContainerBuilder {
foreach(glob($globPath, GLOB_BRACE) as $definitionFile) {
$this->getContainerBuilder()->addDefinitions($definitionFile);
}
return $this;
}
/**
* Uses the wrapped container builder to build the container (duh!) and checks the type for the iContainer interface. If the built container
* is not of type iContainer an exception is thrown.
*
* @return iContainer
* @throws \Exception if the build container was not of type iContainer
*/
public function build() : iContainer {
$container = $this->getContainerBuilder()->build();
if(!$container instanceof iContainer) throw new Exception(sprintf('Built container is not of type %s', iContainer::class));
return $container;
}
}