This repository has been archived by the owner on Jan 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
DelegatorFactory.php
97 lines (84 loc) · 2.5 KB
/
DelegatorFactory.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
<?php
/**
* @see https://github.com/zendframework/zend-auradi-config for the canonical source repository
* @copyright Copyright (c) 2017-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-auradi-config/blob/master/LICENSE.md New BSD License
*/
declare(strict_types=1);
namespace Zend\AuraDi\Config;
use Aura\Di\Container;
use Aura\Di\Exception\ServiceNotFound;
use function class_exists;
use function is_callable;
use function sprintf;
/**
* Aura.Di-compatible delegator factory.
*
* Map an instance of this:
*
* <code>
* $container->set(
* $serviceName,
* $container->lazyGetCall(
* $delegatorFactoryInstance,
* 'build',
* $container,
* $serviceName
* )
* )
* </code>
*
* Instances receive the list of delegator factory names or instances, and a
* closure that can create the initial service instance to pass to the first
* delegator.
*/
class DelegatorFactory
{
/**
* @var array Either delegator factory names or instances.
*/
private $delegators;
/**
* @var callable
*/
private $factory;
/**
* @param array $delegators Array of delegator factory names or instances.
* @param callable $factory Callable that can return the initial instance.
*/
public function __construct(array $delegators, callable $factory)
{
$this->delegators = $delegators;
$this->factory = $factory;
}
/**
* Build the instance, invoking each delegator with the result of the previous.
*
* @return mixed
* @throws ServiceNotFound
*/
public function build(Container $container, string $serviceName)
{
$callback = $this->factory;
foreach ($this->delegators as $delegatorName) {
if (! class_exists($delegatorName)) {
throw new ServiceNotFound(sprintf(
'Delegator class %s does not exist',
$delegatorName
));
}
$delegator = new $delegatorName();
if (! is_callable($delegator)) {
throw new ServiceNotFound(sprintf(
'Delegator class %s is not callable',
$delegatorName
));
}
$instance = $delegator($container, $serviceName, $callback);
$callback = function () use ($instance) {
return $instance;
};
}
return $instance ?? $callback();
}
}