Line data Source code
1 : import 'root/smart_management.dart';
2 : import 'rx/rx_interface.dart';
3 : import 'typedefs.dart';
4 :
5 : class GetConfig {
6 : //////////// INSTANCE MANAGER
7 24 : static Map<dynamic, dynamic> _singl = {};
8 21 : static Map<dynamic, FcBuilderFunc> _factory = {};
9 24 : static Map<String, String> routesKey = {};
10 16 : static SmartManagement smartManagement = SmartManagement.full;
11 : static bool isLogEnable = true;
12 : static String currentRoute;
13 : }
14 :
15 : class GetInstance {
16 8 : factory GetInstance() {
17 8 : if (_getInstance == null) _getInstance = GetInstance._();
18 : return _getInstance;
19 : }
20 8 : GetInstance._();
21 : static GetInstance _getInstance;
22 :
23 3 : void lazyPut<S>(FcBuilderFunc builder, {String tag}) {
24 3 : String key = _getKey(S, tag);
25 9 : GetConfig._factory.putIfAbsent(key, () => builder);
26 : }
27 :
28 1 : Future<S> putAsync<S>(FcBuilderFuncAsync<S> builder, {String tag}) async {
29 3 : return put<S>(await builder(), tag: tag);
30 : }
31 :
32 : /// Inject class on Get Instance Manager
33 8 : S put<S>(
34 : S dependency, {
35 : String tag,
36 : bool permanent = false,
37 : bool overrideAbstract = false,
38 : FcBuilderFunc<S> builder,
39 : }) {
40 8 : _insert(
41 : isSingleton: true,
42 : replace: overrideAbstract,
43 : //?? (("$S" == "${dependency.runtimeType}") == false),
44 : name: tag,
45 : permanent: permanent,
46 8 : builder: builder ?? (() => dependency));
47 8 : return find<S>(tag: tag);
48 : }
49 :
50 : /// Create a new instance from builder class
51 : /// Example
52 : /// create(() => Repl());
53 : /// Repl a = find();
54 : /// Repl b = find();
55 : /// print(a==b); (false)
56 0 : void create<S>(
57 : FcBuilderFunc<S> builder, {
58 : String name,
59 : }) {
60 0 : _insert(isSingleton: false, name: name, builder: builder);
61 : }
62 :
63 8 : void _insert<S>({
64 : bool isSingleton,
65 : String name,
66 : bool replace = true,
67 : bool permanent = false,
68 : FcBuilderFunc<S> builder,
69 : }) {
70 0 : assert(builder != null);
71 8 : String key = _getKey(S, name);
72 : if (replace) {
73 0 : GetConfig._singl[key] = FcBuilder<S>(isSingleton, builder, permanent);
74 : } else {
75 16 : GetConfig._singl.putIfAbsent(
76 16 : key, () => FcBuilder<S>(isSingleton, builder, permanent));
77 : }
78 : }
79 :
80 3 : void removeDependencyByRoute(String routeName) async {
81 3 : List<String> keysToRemove = [];
82 9 : GetConfig.routesKey.forEach((key, value) {
83 : // if (value == routeName && value != null) {
84 3 : if (value == routeName) {
85 0 : keysToRemove.add(key);
86 : }
87 : });
88 3 : keysToRemove.forEach((element) async {
89 0 : await delete(key: element);
90 : });
91 3 : keysToRemove.forEach((element) {
92 0 : GetConfig.routesKey?.remove(element);
93 : });
94 3 : keysToRemove.clear();
95 : }
96 :
97 0 : bool isRouteDependecyNull<S>({String name}) {
98 0 : return (GetConfig.routesKey[_getKey(S, name)] == null);
99 : }
100 :
101 8 : bool isDependencyInit<S>({String name}) {
102 8 : String key = _getKey(S, name);
103 16 : return GetConfig.routesKey.containsKey(key);
104 : }
105 :
106 8 : void registerRouteInstance<S>({String tag}) {
107 : // print("Register route [$S] as ${currentRoute}");
108 8 : GetConfig.routesKey
109 24 : .putIfAbsent(_getKey(S, tag), () => GetConfig.currentRoute);
110 : }
111 :
112 0 : S findByType<S>(Type type, {String tag}) {
113 0 : String key = _getKey(type, tag);
114 0 : return GetConfig._singl[key].getSependency();
115 : }
116 :
117 8 : void initController<S>({String tag}) {
118 8 : String key = _getKey(S, tag);
119 24 : final i = GetConfig._singl[key].getSependency();
120 :
121 8 : if (i is DisposableInterface) {
122 7 : i.onStart();
123 14 : if (GetConfig.isLogEnable) print('[GET] $key has been initialized');
124 : }
125 : }
126 :
127 : /// Find a instance from required class
128 8 : S find<S>({String tag, FcBuilderFunc<S> instance}) {
129 8 : String key = _getKey(S, tag);
130 : bool callInit = false;
131 8 : if (isRegistred<S>(tag: tag)) {
132 8 : if (!isDependencyInit<S>() &&
133 16 : GetConfig.smartManagement != SmartManagement.onlyBuilder) {
134 8 : registerRouteInstance<S>(tag: tag);
135 : callInit = true;
136 : }
137 :
138 16 : FcBuilder builder = GetConfig._singl[key];
139 : if (builder == null) {
140 : if (tag == null) {
141 0 : throw "class ${S.toString()} is not register";
142 : } else {
143 0 : throw "class ${S.toString()} with tag '$tag' is not register";
144 : }
145 : }
146 : if (callInit) {
147 8 : initController<S>(tag: tag);
148 : }
149 :
150 24 : return GetConfig._singl[key].getSependency();
151 : } else {
152 6 : if (!GetConfig._factory.containsKey(key))
153 0 : throw " $S not found. You need call put<$S>($S()) before";
154 :
155 : if (GetConfig.isLogEnable)
156 6 : print('[GET] $S instance was created at that time');
157 12 : S _value = put<S>(GetConfig._factory[key].call() as S);
158 :
159 3 : if (!isDependencyInit<S>() &&
160 0 : GetConfig.smartManagement != SmartManagement.onlyBuilder) {
161 0 : registerRouteInstance<S>(tag: tag);
162 : callInit = true;
163 : }
164 :
165 6 : if (GetConfig.smartManagement != SmartManagement.keepFactory) {
166 6 : GetConfig._factory.remove(key);
167 : }
168 :
169 : if (callInit) {
170 0 : initController<S>(tag: tag);
171 : }
172 : return _value;
173 : }
174 : }
175 :
176 : /// Remove dependency of [S] on dependency abstraction. For concrete class use delete
177 0 : void remove<S>({String tag}) {
178 0 : String key = _getKey(S, tag);
179 0 : FcBuilder builder = GetConfig._singl[key];
180 0 : final i = builder.dependency;
181 :
182 0 : if (i is DisposableInterface) {
183 0 : i.onClose();
184 0 : if (GetConfig.isLogEnable) print('[GET] onClose of $key called');
185 : }
186 0 : if (builder != null) builder.dependency = null;
187 0 : if (GetConfig._singl.containsKey(key)) {
188 0 : print('error on remove $key');
189 : } else {
190 0 : if (GetConfig.isLogEnable) print('[GET] $key removed from memory');
191 : }
192 : }
193 :
194 8 : String _getKey(Type type, String name) {
195 8 : return name == null ? type.toString() : type.toString() + name;
196 : }
197 :
198 1 : bool reset({bool clearFactory = true, bool clearRouteBindings = true}) {
199 2 : if (clearFactory) GetConfig._factory.clear();
200 2 : if (clearRouteBindings) GetConfig.routesKey.clear();
201 2 : GetConfig._singl.clear();
202 : return true;
203 : }
204 :
205 : /// Delete class instance on [S] and clean memory
206 6 : Future<bool> delete<S>({String tag, String key}) async {
207 : String newKey;
208 : if (key == null) {
209 6 : newKey = _getKey(S, tag);
210 : } else {
211 : newKey = key;
212 : }
213 :
214 12 : if (!GetConfig._singl.containsKey(newKey)) {
215 0 : print('Instance $newKey not found');
216 : return false;
217 : }
218 :
219 12 : FcBuilder builder = GetConfig._singl[newKey];
220 6 : if (builder.permanent) {
221 : (key == null)
222 0 : ? print(
223 0 : '[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.')
224 0 : : print(
225 0 : '[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.');
226 : return false;
227 : }
228 6 : final i = builder.dependency;
229 :
230 6 : if (i is DisposableInterface) {
231 12 : await i.onClose();
232 12 : if (GetConfig.isLogEnable) print('[GET] onClose of $newKey called');
233 : }
234 :
235 24 : GetConfig._singl.removeWhere((oldkey, value) => (oldkey == newKey));
236 12 : if (GetConfig._singl.containsKey(newKey)) {
237 0 : print('[GET] error on remove object $newKey');
238 : } else {
239 12 : if (GetConfig.isLogEnable) print('[GET] $newKey deleted from memory');
240 : }
241 : // GetConfig.routesKey?.remove(key);
242 : return true;
243 : }
244 :
245 : /// check if instance is registred
246 8 : bool isRegistred<S>({String tag}) =>
247 24 : GetConfig._singl.containsKey(_getKey(S, tag));
248 :
249 : /// check if instance is prepared
250 6 : bool isPrepared<S>({String tag}) =>
251 18 : GetConfig._factory.containsKey(_getKey(S, tag));
252 : }
|