-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNanoInject.java
More file actions
129 lines (108 loc) · 3.83 KB
/
NanoInject.java
File metadata and controls
129 lines (108 loc) · 3.83 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* abstract of class/interface and so on
*
* @author kailun on 16/4/19
*/
public class NanoInject {
private static class Binder<T> {
Class<T> bindClass;
Class<? extends T> toClass;
Provider<T> provider;
T toInstance;
}
public static class Builder {
List<Binder> binders = new ArrayList<>();
public <T> void bind(Class<T> bindClass, Class<? extends T> toClass) {
Binder<T> binder = new Binder<T>();
binder.bindClass = bindClass;
binder.toClass = toClass;
binders.add(binder);
}
public <T> void bindInstance(Class<T> bindClass, T toInstance) {
Binder<T> binder = new Binder<T>();
binder.bindClass = bindClass;
binder.toInstance = toInstance;
binders.add(binder);
}
public <T> void bindProvider(Class<T> bindClass, Provider<T> provider) {
Binder<T> binder = new Binder<T>();
binder.bindClass = bindClass;
binder.provider = provider;
binders.add(binder);
}
}
public interface Provider<T> {
T get();
}
private static NanoInject sInstance;
public static NanoInject instance() {
if (sInstance == null) {
throw new RuntimeException("NanoInject not inited");
}
return sInstance;
}
public static void init(Builder builder) {
NanoInject inject = new NanoInject();
inject.initInject(builder);
sInstance = inject;
}
private HashMap<Class, Class> classBinders;
private HashMap<Class, Object> instanceBinders;
private HashMap<Class, Provider<?>> providerBinders;
{
classBinders = new HashMap<>();
instanceBinders = new HashMap<>();
providerBinders = new HashMap<>();
}
private NanoInject() {
}
private void initInject(Builder builder) {
List<Binder> binders = builder.binders;
for (Binder b: binders) {
if (b.toClass != null) {
classBinders.put(b.bindClass, b.toClass);
} else if (b.toInstance != null) {
instanceBinders.put(b.bindClass, b.toInstance);
} else if (b.provider != null) {
providerBinders.put(b.bindClass, b.provider);
}
else {
throw new RuntimeException("toClass and toInstance both null");
}
}
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> bindClass) {
if (instanceBinders.containsKey(bindClass)) {
T toInstance = (T) instanceBinders.get(bindClass);
if (toInstance == null) {
throw new RuntimeException("cant resolve dependcy: " + bindClass.getName());
}
return toInstance;
}
else if (classBinders.containsKey(bindClass)) {
Class<T> toClass = classBinders.get(bindClass);
if (toClass == null) {
throw new RuntimeException("cant resolve dependcy: " + bindClass.getName());
}
try {
return (T) toClass.newInstance();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
} else if (providerBinders.containsKey(bindClass)) {
Provider<T> provider = (Provider<T>) providerBinders.get(bindClass);
if (provider == null) {
throw new RuntimeException("cant resolve dependcy: " + bindClass.getName());
}
return provider.get();
} else {
throw new RuntimeException("cant find bindClass: " + bindClass.getName());
}
}
}