Skip to content

Commit 07fd8d7

Browse files
Implement Reliese Dependency Container
0 parents  commit 07fd8d7

File tree

5 files changed

+462
-0
lines changed

5 files changed

+462
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
/vendor
3+
/.idea

composer.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "reliese/dependency",
3+
"description": "Dependency Container",
4+
"keywords": ["reliese", "dependency"],
5+
"license": "MIT",
6+
"type": "library",
7+
"authors": [
8+
{
9+
"name": "Cristian Llanos",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"support": {
14+
"issues": "https://github.com/reliese/php-dependency/issues",
15+
"source": "https://github.com/reliese/php-dependency"
16+
},
17+
"require": {
18+
"php": ">=7.2",
19+
"reliese/component-dependency": "^1.0"
20+
},
21+
"require-dev": {
22+
"kahlan/kahlan": "^4.6"
23+
},
24+
"autoload": {
25+
"psr-4": {
26+
"Reliese\\Dependency\\": "src/"
27+
}
28+
},
29+
"prefer-stable": true
30+
}

readme.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Reliese Dependency
2+
3+
This is the implementation of Reliese Component Dependency. An actual Dependency Container.

spec/Container.spec.php

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<?php
2+
3+
use Reliese\Dependency\Container;
4+
5+
describe("Container", function () {
6+
describe("Registered Dependencies", function () {
7+
it("resolves a registered dependency", function () {
8+
$container = new Container();
9+
10+
$container->register(OneSimpleDependency::class, function () {
11+
return new OneSimpleDependency();
12+
});
13+
14+
$resolve = function () use ($container) {
15+
expect($container->resolve(OneSimpleDependency::class))->toBeAnInstanceOf(OneSimpleDependency::class);
16+
};
17+
18+
expect($resolve)->not->toThrow();
19+
});
20+
21+
it("resolves a singleton registered dependency", function () {
22+
$container = new Container();
23+
24+
$container->singleton(OneSimpleDependency::class, function () {
25+
return new OneSimpleDependency();
26+
});
27+
28+
$resolve = function () use ($container) {
29+
$firstInstance = $container->resolve(OneSimpleDependency::class);
30+
expect($firstInstance)->toBeAnInstanceOf(OneSimpleDependency::class);
31+
32+
$secondInstance = $container->resolve(OneSimpleDependency::class);
33+
expect($secondInstance)->toBeAnInstanceOf(OneSimpleDependency::class);
34+
35+
expect($firstInstance)->toBe($secondInstance);
36+
};
37+
38+
expect($resolve)->not->toThrow();
39+
});
40+
41+
it("resolves an abstract dependency to an instantiable dependency", function() {
42+
$container = new Container();
43+
44+
$container->register(RegisteredAbstractDependency::class, function () {
45+
return new AnotherSimpleDependency();
46+
});
47+
48+
$resolve = function () use ($container) {
49+
expect($container->resolve(RegisteredAbstractDependency::class))->toBeAnInstanceOf(AnotherSimpleDependency::class);
50+
};
51+
52+
expect($resolve)->not->toThrow();
53+
});
54+
55+
it("resolves a registered dependency on a method call", function () {
56+
$container = new Container();
57+
58+
$container->register(OneSimpleDependency::class, function () {
59+
return new OneSimpleDependency();
60+
});
61+
62+
$resolve = function () use ($container) {
63+
$object = new OneSimpleDependencyWithMethodDependencies();
64+
expect($container->call($object, 'handle'))->toBeAnInstanceOf(OneSimpleDependency::class);
65+
};
66+
67+
$resolve();
68+
69+
// expect($resolve)->not->toThrow();
70+
});
71+
});
72+
73+
describe("Unregistered Dependencies", function () {
74+
describe("Unresolvable Dependencies", function () {
75+
it("cannot resolve an unregistered abstract dependency", function () {
76+
$container = new Container();
77+
78+
$resolve = function () use ($container) {
79+
$container->resolve(NotRegisteredAbstractDependency::class);
80+
};
81+
82+
expect($resolve)->toThrow();
83+
});
84+
85+
it("cannot resolve a complex dependency when it depends on a not registered interface", function() {
86+
$container = new Container();
87+
88+
$resolve = function () use ($container) {
89+
return $container->resolve(NotResolvableComplexDependency::class);
90+
};
91+
92+
expect($resolve)->toThrow();
93+
});
94+
});
95+
96+
describe("Resolvable Dependencies", function () {
97+
it("resolves a simple dependency", function () {
98+
$container = new Container();
99+
100+
$resolve = function () use ($container) {
101+
expect($container->resolve(OneSimpleDependency::class))->toBeAnInstanceOf(OneSimpleDependency::class);
102+
};
103+
104+
expect($resolve)->not->toThrow();
105+
});
106+
107+
it("resolves a complex dependency", function () {
108+
$container = new Container();
109+
110+
$cases = [
111+
OneComplexDependency::class,
112+
ResolvableComplexDependencyWithDefaultValuesInTheMiddle::class
113+
];
114+
115+
foreach ($cases as $dependency) {
116+
$resolve = function () use ($container, $dependency) {
117+
expect($container->resolve($dependency))->toBeAnInstanceOf($dependency);
118+
};
119+
120+
expect($resolve)->not->toThrow();
121+
}
122+
});
123+
124+
it("resolves a complex dependency when it depends on registered abstract dependencies", function () {
125+
$container = new Container();
126+
127+
$container->register(RegisteredAbstractDependency::class, function () {
128+
return new AnotherSimpleDependency();
129+
});
130+
131+
$resolve = function () use ($container) {
132+
expect($container->resolve(AnotherComplexDependency::class))->toBeAnInstanceOf(AnotherComplexDependency::class);
133+
};
134+
135+
expect($resolve)->not->toThrow();
136+
});
137+
138+
it("resolves a deep complex dependency when it depends on registered abstract dependencies", function () {
139+
$container = new Container();
140+
141+
$container->register(RegisteredAbstractDependency::class, function () {
142+
return new AnotherSimpleDependency();
143+
});
144+
145+
$resolve = function () use ($container) {
146+
$resolved = $container->resolve(DeepComplexDependency::class);
147+
expect($resolved)->toBeAnInstanceOf(DeepComplexDependency::class);
148+
};
149+
150+
expect($resolve)->not->toThrow();
151+
});
152+
});
153+
154+
describe("Dependencies with primitive type params", function () {
155+
it("cannot resolve complex dependencies when it depends on primitive types", function () {
156+
$container = new Container();
157+
158+
$resolve = function () use ($container) {
159+
$container->resolve(UnresolvableComplexDependency::class);
160+
};
161+
162+
expect($resolve)->toThrow();
163+
});
164+
165+
it("can resolve complex dependencies when it depends on optional primitive types", function () {
166+
$container = new Container();
167+
168+
$container->register(RegisteredAbstractDependency::class, function () {
169+
return new AnotherSimpleDependency();
170+
});
171+
172+
$resolve = function () use ($container) {
173+
$resolved = $container->resolve(ResolvableComplexDependency::class);
174+
expect($resolved)->toBeAnInstanceOf(ResolvableComplexDependency::class);
175+
};
176+
177+
expect($resolve)->not->toThrow();
178+
});
179+
});
180+
});
181+
});
182+
183+
interface RegisteredAbstractDependency {}
184+
interface NotRegisteredAbstractDependency {};
185+
class OneSimpleDependency {};
186+
class OneSimpleDependencyWithMethodDependencies { public function handle(OneSimpleDependency $a): OneSimpleDependency { return $a; } };
187+
class AnotherSimpleDependency implements RegisteredAbstractDependency {};
188+
class OneComplexDependency { public function __construct(OneSimpleDependency $a, AnotherSimpleDependency $b) {} };
189+
class AnotherComplexDependency { public function __construct(OneSimpleDependency $a, RegisteredAbstractDependency $b) {} };
190+
class NotResolvableComplexDependency { public function __construct(OneSimpleDependency $a, NotRegisteredAbstractDependency $b) {} };
191+
class DeepComplexDependency { public function __construct(AnotherComplexDependency $a, RegisteredAbstractDependency $b){} };
192+
class UnresolvableComplexDependency { public function __construct(AnotherComplexDependency $a, string $b){} };
193+
class ResolvableComplexDependency { public function __construct(AnotherComplexDependency $a, string $b = "hola"){} };
194+
class ResolvableComplexDependencyWithDefaultValuesInTheMiddle { public function __construct(OneSimpleDependency $a, string $b = "hola", OneSimpleDependency $c){} };

0 commit comments

Comments
 (0)