Skip to content

Commit 0af3b5b

Browse files
committed
feat(structural): implement DI container
1 parent db01974 commit 0af3b5b

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import "reflect-metadata";
2+
3+
namespace InversionOfControlContainer {
4+
interface Type<T> {
5+
new (...args: any[]): T;
6+
}
7+
8+
abstract class Container {
9+
public static designParamTypes = "design:paramtypes";
10+
public static designType = "design:type";
11+
12+
private static bean = new Map<string, any>();
13+
14+
static get<T>(target: Type<T>): T {
15+
if (this.bean.has(target.name)) {
16+
return this.bean.get(target.name);
17+
}
18+
19+
const tokens: Type<any>[] =
20+
Reflect.getMetadata(this.designParamTypes, target) || [];
21+
22+
const injections = tokens.map((token) => {
23+
return Container.get(token);
24+
});
25+
26+
const instance = new target(...injections);
27+
this.bean.set(target.name, instance);
28+
29+
return instance;
30+
}
31+
}
32+
33+
function Injectable() {
34+
return function <T>(target: Type<T>) {
35+
Reflect.getMetadata(Container.designParamTypes, target);
36+
};
37+
}
38+
39+
@Injectable()
40+
class UserRepository {
41+
findById(id: number) {
42+
return { user: "user", id };
43+
}
44+
}
45+
46+
@Injectable()
47+
class PostRepository {
48+
getUserPosts(userId: number) {
49+
return [
50+
{ title: "post1", userId },
51+
{ title: "post2", userId },
52+
];
53+
}
54+
}
55+
56+
@Injectable()
57+
class BlogService {
58+
constructor(
59+
private readonly userRepository: UserRepository,
60+
private readonly postRepository: PostRepository
61+
) {}
62+
63+
getBlogInfo(id: number) {
64+
const user = this.userRepository.findById(id);
65+
const posts = this.postRepository.getUserPosts(id);
66+
67+
return { user, posts };
68+
}
69+
}
70+
71+
const blogService = Container.get(BlogService);
72+
73+
blogService.getBlogInfo(1);
74+
}
75+
76+
/**
77+
* Inversion of Control Container or Dependency Inversion
78+
*
79+
* Higher modules of our application should not be aware about lower modules and implementation details.
80+
* It makes the code low coupled and manageable. The IoC and DI is the techniques to achieve the desired
81+
* decoupling.
82+
*
83+
* High feature module imagines that he has some higher level methods for his needs. The class uses it
84+
* without knowing much about the implementation.
85+
*
86+
*/

0 commit comments

Comments
 (0)