Completed
Push — develop ( f25192...c2ccd8 )
by John
05:07 queued 02:11
created

ServiceFactory   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 12
c 0
b 0
f 0
lcom 1
cbo 2
dl 0
loc 75
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
C getInstance() 0 39 12
1
<?php
2
3
namespace Alpha\Util\Service;
4
5
use Alpha\Exception\IllegalArguementException;
6
use Alpha\Util\Logging\Logger;
7
8
/**
9
 * A factory for creating service instances that match the provider name and interface provided
10
 *
11
 * @since 3.0
12
 *
13
 * @author John Collins <[email protected]>
14
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
15
 * @copyright Copyright (c) 2017, John Collins (founder of Alpha Framework).
16
 * All rights reserved.
17
 *
18
 * <pre>
19
 * Redistribution and use in source and binary forms, with or
20
 * without modification, are permitted provided that the
21
 * following conditions are met:
22
 *
23
 * * Redistributions of source code must retain the above
24
 *   copyright notice, this list of conditions and the
25
 *   following disclaimer.
26
 * * Redistributions in binary form must reproduce the above
27
 *   copyright notice, this list of conditions and the
28
 *   following disclaimer in the documentation and/or other
29
 *   materials provided with the distribution.
30
 * * Neither the name of the Alpha Framework nor the names
31
 *   of its contributors may be used to endorse or promote
32
 *   products derived from this software without specific
33
 *   prior written permission.
34
 *
35
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
36
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
37
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
40
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48
 * </pre>
49
 */
50
class ServiceFactory
51
{
52
    /**
53
     * Trace logger.
54
     *
55
     * @var \Alpha\Util\Logging\Logger
56
     *
57
     * @since 3.0
58
     */
59
    private static $logger = null;
60
61
    /**
62
     * A static array of service singletons in case any service needs to be accessed as a single instance.
63
     *
64
     * @var array
65
     *
66
     * @since 3.0
67
     */
68
    private static $singletons = array();
69
70
    /**
71
     * A static method that attempts to return a service provider instance
72
     * based on the name of the provider class supplied.  If the instance does not
73
     * implement the desired interface, an exception is thrown.
74
     *
75
     * @param string $serviceName The class name of the service class (fully qualified).
76
     * @param string $serviceInterface The interface name of the service class returned (fully qualified).
77
     * @param bool   $isSingleton Set to true if the service instance requested is a singleton, default is false (you get a new instance each time).
78
     *
79
     * @throws \Alpha\Exception\IllegalArguementException
80
     *
81
     * @return \stdClass
82
     *
83
     * @since 3.0
84
     */
85
    public static function getInstance($serviceName, $serviceInterface, $isSingleton = false)
86
    {
87
        // as the LogProviderInterface is itself a service, we don't call it's constructor again during instantiation
88
        if (self::$logger === null && $serviceInterface != 'Alpha\Util\Logging\LogProviderInterface') {
89
            self::$logger = new Logger('ServiceFactory');
90
        }
91
92
        if (self::$logger !== null) {
93
            self::$logger->debug('>>getInstance(serviceName=['.$serviceName.'], serviceInterface=['.$serviceInterface.'], isSingleton=['.$isSingleton.'])');
94
        }
95
96
        if (class_exists($serviceName)) {
97
            if ($isSingleton && in_array($serviceName, self::$singletons)) {
98
                return self::$singletons[$serviceName];
99
            }
100
101
            $instance = new $serviceName();
102
103
            if (!$instance instanceof $serviceInterface) {
104
                throw new IllegalArguementException('The class ['.$serviceName.'] does not implement the expected ['.$serviceInterface.'] interface!');
105
            }
106
107
            if ($isSingleton && !in_array($serviceName, self::$singletons)) {
108
                self::$singletons[$serviceName] = $instance;
109
            }
110
111
            if (self::$logger !== null) {
112
                self::$logger->debug('<<getInstance: [Object '.$serviceName.']');
113
            }
114
115
            return $instance;
116
        } else {
117
            if (self::$logger !== null) {
118
                self::$logger->debug('<<getInstance');
119
            }
120
121
            throw new IllegalArguementException('The class ['.$serviceName.'] is not defined anywhere!');
122
        }
123
    }
124
}
125