Completed
Push — master ( 23b6a7...8b7e63 )
by James Ekow Abaka
01:56
created

Container   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

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

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getResolvedClassName() 0 9 4
A bind() 0 3 1
A singleton() 0 4 1
A getSingletonInstance() 0 6 2
A resolve() 0 14 4
C getInstance() 0 27 7
1
<?php
2
3
namespace ntentan\panie;
4
5
/**
6
 * Description of Container
7
 *
8
 * @author ekow
9
 */
10
class Container {
11
12
    private $bindings;
13
    private $singletons = [];
14
15
    public function __construct() {
16
        $this->bindings = new Bindings();
17
    }
18
19
    /**
20
     * 
21
     * @param string|\ReflectionClass $class
22
     * @return \ReflectionClass
23
     */
24
    public function getResolvedClassName($class) {
25
        $bound = null;
26
        if ($this->bindings->has($class)) {
27
            $bound = $this->bindings->get($class);
28
        } else if (is_string($class) && class_exists($class)) {
29
            $bound = ['class' => $class];
30
        }     
31
        return $bound;
32
    }
33
34
    public function bind($lose) {
35
        return $this->bindings->setActiveKey($lose);
36
    }
37
38
    public function singleton($type, $constructorArguments = []) {
39
        $resolvedClass = $this->getResolvedClassName($type)['class'];
40
        return $this->getSingletonInstance($type, $resolvedClass, $constructorArguments);
41
    }
42
    
43
    private function getSingletonInstance($type, $class,  $constructorArguments) {
44
        if (!isset($this->singletons[$type])) {
45
            $this->singletons[$type] = $this->getInstance($class, $constructorArguments);
46
        }
47
        return $this->singletons[$type];        
48
    }
49
    
50
    public function resolve($type, $constructorArguments = []) {
51
        if($type === null) {
52
            throw new exceptions\ResolutionException("Cannot resolve an empty type");
53
        }
54
        $resolvedClass = $this->getResolvedClassName($type);
55
        if ($resolvedClass['class'] === null) {
56
            throw new exceptions\ResolutionException("Could not resolve dependency $type");
57
        }           
58
        if(isset($resolvedClass['singleton'])) {
59
            return $this->getSingletonInstance($type, $resolvedClass['class'], $constructorArguments);
60
        } else {
61
            return $this->getInstance($resolvedClass['class'], $constructorArguments);
62
        }
63
    }
64
65
    public function getInstance($className, $constructorArguments = []) {
66
        
67
        $reflection = new \ReflectionClass($className);
68
        if ($reflection->isAbstract()) {
69
            throw new exceptions\ResolutionException(
70
            "Abstract class {$reflection->getName()} cannot be instantiated. "
71
            . "Please provide a binding to an implementation."
72
            );
73
        }
74
        $constructor = $reflection->getConstructor();
75
        $instanceParameters = [];
76
77
        if ($constructor != null) {
78
            $parameters = $constructor->getParameters();
79
            foreach ($parameters as $parameter) {
80
                $class = $parameter->getClass();
81
                if (isset($constructorArguments[$parameter->getName()])) {
82
                    $instanceParameters[] = $constructorArguments[$parameter->getName()];
83
                } else if($class == self::class){
84
                    $instanceParameters[] = $this;
85
                } else {                    
86
                    $instanceParameters[] = $class ? $this->resolve($class->getName()) : null;
87
                }
88
            }
89
        }
90
        return $reflection->newInstanceArgs($instanceParameters);
91
    }
92
93
}
94