@kaokei/di 1.0.21 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +20 -103
  3. package/dist/index.cjs.js +450 -233
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.cjs.min.js +3 -3
  6. package/dist/index.cjs.min.js.map +1 -1
  7. package/dist/index.cjs.runtime.js +444 -229
  8. package/dist/index.cjs.runtime.js.map +1 -1
  9. package/dist/index.cjs.runtime.min.js +3 -3
  10. package/dist/index.cjs.runtime.min.js.map +1 -1
  11. package/dist/index.esm.js +451 -219
  12. package/dist/index.esm.js.map +1 -1
  13. package/dist/index.esm.min.js +4 -4
  14. package/dist/index.esm.min.js.map +1 -1
  15. package/dist/index.esm.runtime.js +439 -214
  16. package/dist/index.esm.runtime.js.map +1 -1
  17. package/dist/index.esm.runtime.min.js +4 -4
  18. package/dist/index.esm.runtime.min.js.map +1 -1
  19. package/dist/index.iife.js +457 -237
  20. package/dist/index.iife.js.map +1 -1
  21. package/dist/index.iife.min.js +4 -4
  22. package/dist/index.iife.min.js.map +1 -1
  23. package/dist/src/Injector.d.ts +67 -32
  24. package/dist/src/Injector.d.ts.map +1 -1
  25. package/dist/src/constants.d.ts +5 -11
  26. package/dist/src/constants.d.ts.map +1 -1
  27. package/dist/src/decorator.d.ts +13 -1
  28. package/dist/src/decorator.d.ts.map +1 -1
  29. package/dist/src/errors/CircularDependencyError.d.ts +6 -0
  30. package/dist/src/errors/CircularDependencyError.d.ts.map +1 -0
  31. package/dist/src/errors/InjectFailedError.d.ts +6 -0
  32. package/dist/src/errors/InjectFailedError.d.ts.map +1 -0
  33. package/dist/src/errors/ProviderNotValidError.d.ts +6 -0
  34. package/dist/src/errors/ProviderNotValidError.d.ts.map +1 -0
  35. package/dist/src/errors/TokenNotFoundError.d.ts +6 -0
  36. package/dist/src/errors/TokenNotFoundError.d.ts.map +1 -0
  37. package/dist/src/errors/index.d.ts +5 -0
  38. package/dist/src/errors/index.d.ts.map +1 -0
  39. package/dist/src/index.d.ts +1 -1
  40. package/dist/src/index.d.ts.map +1 -1
  41. package/package.json +5 -7
  42. package/dist/.DS_Store +0 -0
@@ -1,48 +1,61 @@
1
1
  import _construct from "@babel/runtime/helpers/esm/construct";
2
2
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
3
- import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
4
3
  import _createClass from "@babel/runtime/helpers/esm/createClass";
4
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
5
+ import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
6
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
7
+ import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
8
+ import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
9
+ import _wrapNativeSuper from "@babel/runtime/helpers/esm/wrapNativeSuper";
5
10
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
6
11
 
12
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
13
+
14
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15
+
16
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
17
+
18
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
19
+
7
20
  /**
8
21
  * @kaokei/di
9
- * jsbridge for iframes or windows by window.postMessage
22
+ * Tiny di library depend on typescript and reflect-metadata
10
23
  *
11
- * @version 1.0.21
24
+ * @version 1.0.25
12
25
  * @author kaokei
13
26
  * @license MIT
14
27
  * @link https://github.com/kaokei/di
15
28
  */
16
- export { default as autobind } from 'autobind-decorator';
17
- var DESIGN_PARAM_TYPES = 'design:paramtypes'; // ts自带的类的构造函数的参数的类型信息的key
18
-
19
- var SERVICE_PARAM_TYPES = 'service:paramtypes'; // 构造函数原始的类型数据,可能会被@Inject等覆盖
20
-
21
- var SERVICE_INJECTED_PARAMS = 'service:injected:params'; // 构造函数使用@Inject注入的数据
22
-
23
- var SERVICE_INJECTED_PROPS = 'service:injected:props'; // @Inject注入的properties
24
-
25
29
  var DECORATOR_KEYS = {
30
+ // ts自带的类的实例属性的类型的key
31
+ DESIGN_PROPERTY_TYPE: 'design:type',
32
+ // ts自带的类的构造函数的参数的类型信息的key
33
+ DESIGN_PARAM_TYPES: 'design:paramtypes',
34
+ // 记录构造函数原始的类型数据的key,其实就是转存了DESIGN_PARAM_TYPES对应的数据
35
+ SERVICE_PARAM_TYPES: 'service:paramtypes',
36
+ // 记录构造函数参数装饰器对应的数据的key
37
+ SERVICE_INJECTED_PARAMS: 'service:injected:params',
38
+ // 记录实例属性装饰器对应的数据的key
39
+ SERVICE_INJECTED_PROPS: 'service:injected:props',
40
+ // Inject装饰器的key
26
41
  INJECT: Symbol('inject'),
42
+ // Injectable装饰器的key
27
43
  INJECTABLE: Symbol('injectable'),
44
+ // Self装饰器的key
28
45
  SELF: 'self',
46
+ // Skip装饰器的key
29
47
  SKIP_SELF: 'skip',
30
- OPTIONAL: 'optional',
31
- DEFAULT_VALUE: 'defaultValue'
48
+ // Optional装饰器的key
49
+ OPTIONAL: 'optional'
32
50
  };
33
51
  var SERVICE_STATUS = {
34
52
  INITING: Symbol('initing'),
35
53
  CONSTRUCTED: Symbol('constructed'),
36
- MERGED: Symbol('merged'),
37
- INITED: Symbol('inited')
38
- }; // 以下是error message常量
39
-
40
- var ERROR_CIRCULAR_DEPENDENCY = 'CIRCULAR DEPENDENCY DETECTED. PLEASE FIX IT MANUALLY.';
41
- var ERROR_DISABLE_MULTIPLE_INJECTABLE = 'Use multiple @Injectable on same class is not valid.';
42
- var ERROR_TOKEN_NOT_FOUND = 'Token not found.';
43
- var ERROR_INJECT_NOT_VALID = "You may forget to use @Inject on class property or @Injects's parameter is undefined.";
44
- var ERROR_PROVIDER_NOT_VALID = "Provider is not valid.";
54
+ MERGED: Symbol('merged')
55
+ };
45
56
  /**
57
+ * 这里记录不同的装饰器的参数的含义
58
+ *
46
59
  * class decorator:
47
60
  * 只有一个参数:构造函数
48
61
  * property decorator:
@@ -60,42 +73,79 @@ var ERROR_PROVIDER_NOT_VALID = "Provider is not valid.";
60
73
  * 实例访问器:原型, 方法名, 属性描述符
61
74
  */
62
75
 
63
- function createPropertyDecorator(decoratorKey, defaultValue) {
76
+ /**
77
+ * 创建装饰器的高阶函数
78
+ * 装饰器的通用逻辑就是通过Reflect记录到全局的Map中
79
+ * 所以可以抽象出一个通用逻辑,这里需要注意对Inject装饰器有特殊判断
80
+ *
81
+ * @param {(string | symbol)} decoratorKey 代表某个装饰器的名称
82
+ * @param {*} [defaultValue] 该装饰器函数的默认参数
83
+ * @return {*} 一个装饰器
84
+ */
85
+
86
+ function createDecorator(decoratorKey, defaultValue) {
87
+ // 因为装饰器本身作为一个函数是有参数的,此处的decoratorValue就是实际使用装饰器的实参
64
88
  return function (decoratorValue) {
89
+ // 目前的装饰器只支持类的构造函数参数装饰器和类的实例属性装饰器
90
+ // target可能是构造函数或者类的原型
91
+ // 如果target是构造函数,targetKey是undefined,index是参数的位置下标
92
+ // 如果target是原型,targetKey是属姓名,index是undefined
65
93
  return function (target, targetKey, index) {
66
- var isParameterDecorator = typeof index === 'number';
67
- var Ctor = isParameterDecorator ? target : target.constructor;
68
- var key = index !== undefined && isParameterDecorator ? index : targetKey;
69
- var metadataKey = isParameterDecorator ? SERVICE_INJECTED_PARAMS : SERVICE_INJECTED_PROPS;
94
+ // 如果indexnumber,那么代表是构造函数的参数的装饰器
95
+ var isParameterDecorator = typeof index === 'number'; // 统一把装饰器数据绑定到构造函数上,后续获取数据比较方便
96
+
97
+ var Ctor = isParameterDecorator ? target : target.constructor; // 如果是构造函数的参数装饰器,取参数位置下标,否则取实例属性的属性名
98
+
99
+ var key = isParameterDecorator ? index : targetKey; // 区分构造函数的参数装饰器和实例属性的装饰器
100
+ // 分别记录到全局Map的不同位置,metadataKey不一样
101
+
102
+ var metadataKey = isParameterDecorator ? DECORATOR_KEYS.SERVICE_INJECTED_PARAMS : DECORATOR_KEYS.SERVICE_INJECTED_PROPS; // 这里是一个大对象,对应的key是metadataKey
103
+ // 所以全局Map中有两个不同的metadataKey,以及对应的数据对象
104
+ // 如果是构造函数参数装饰器,这个对象中的key是参数位置下标
105
+ // 如果是实例属性装饰器,这个对象中的key是属性名
106
+
70
107
  var paramsOrPropertiesMetadata = Reflect.getMetadata(metadataKey, Ctor) || {}; // 每个参数或者实例属性都可以有多个装饰器
108
+ // 所以paramsOrPropertiesMetadata这个大对象的每个key对应的value都是一个数组
109
+ // 该数组中的每一个元素是一个对象,保存着每一个装饰器的数据
71
110
 
72
111
  var paramOrPropertyMetadata = paramsOrPropertiesMetadata[key] || [];
73
112
  var metadata = {
113
+ // 装饰器的名称
74
114
  key: decoratorKey,
75
- value: decoratorValue || defaultValue
115
+ // 装饰器的值,即装饰器函数的实参
116
+ // 很多装饰器具有默认值,可以不提供实参,而是使用默认值
117
+ value: decoratorValue === void 0 ? defaultValue : decoratorValue
76
118
  };
77
119
 
78
- if (decoratorKey === DECORATOR_KEYS.INJECT) {
79
- if (!decoratorValue) {
80
- throw new Error('没有提供Inject Key');
120
+ if (!isParameterDecorator) {
121
+ if (decoratorKey === DECORATOR_KEYS.INJECT) {
122
+ if (decoratorValue === void 0) {
123
+ // 是实例属性装饰器,且是Inject装饰器,且没有指定参数
124
+ // 需要获取默认的类型数据
125
+ metadata.value = Reflect.getMetadata(DECORATOR_KEYS.DESIGN_PROPERTY_TYPE, target, targetKey);
126
+ }
81
127
  }
82
- }
128
+ } // 把当前装饰器的数据对象放到数组中
129
+
130
+
131
+ paramOrPropertyMetadata.push(metadata); // 关联这个数组和对应的key
132
+
133
+ paramsOrPropertiesMetadata[key] = paramOrPropertyMetadata; // 再把整个大对象放到全局Map中
83
134
 
84
- paramOrPropertyMetadata.push(metadata);
85
- paramsOrPropertiesMetadata[key] = paramOrPropertyMetadata;
86
135
  Reflect.defineMetadata(metadataKey, paramsOrPropertiesMetadata, Ctor);
87
136
  };
88
137
  };
89
138
  } // 可以使用在类构造函数的参数中和类的实例属性中
90
139
 
91
140
 
92
- var Inject = createPropertyDecorator(DECORATOR_KEYS.INJECT); // 指定只在当前injector中寻找服务
141
+ var Inject = createDecorator(DECORATOR_KEYS.INJECT); // 指定只在当前injector中寻找服务
93
142
 
94
- var Self = createPropertyDecorator(DECORATOR_KEYS.SELF, true); // 指定跳过当前injector寻找服务
143
+ var Self = createDecorator(DECORATOR_KEYS.SELF, true); // 指定跳过当前injector寻找服务
95
144
 
96
- var Skip = createPropertyDecorator(DECORATOR_KEYS.SKIP_SELF, true); // 指定服务是可选的,找不到服务时返回undefined,否则抛出异常
145
+ var Skip = createDecorator(DECORATOR_KEYS.SKIP_SELF, true); // 指定服务是可选的,找不到服务时返回undefined,否则抛出异常
146
+ // 其实应该说是默认情况下找不到服务时,会抛出异常,除非明确指定是optional的
97
147
 
98
- var Optional = createPropertyDecorator(DECORATOR_KEYS.OPTIONAL, true);
148
+ var Optional = createDecorator(DECORATOR_KEYS.OPTIONAL, true);
99
149
  /**
100
150
  * 表明服务可注入
101
151
  * 主要工作就是收集构造函数的参数类型信息
@@ -106,15 +156,15 @@ var Optional = createPropertyDecorator(DECORATOR_KEYS.OPTIONAL, true);
106
156
 
107
157
  function Injectable() {
108
158
  return function (target) {
109
- if (Reflect.hasOwnMetadata(SERVICE_PARAM_TYPES, target)) {
110
- throw new Error(ERROR_DISABLE_MULTIPLE_INJECTABLE);
111
- }
112
-
113
- var types = Reflect.getMetadata(DESIGN_PARAM_TYPES, target) || []; // 存储构造函数的类型信息
159
+ // 标记这个类可以注入
160
+ Reflect.defineMetadata(DECORATOR_KEYS.INJECTABLE, true, target); // 获取ts编译器默认的类型数据
161
+ // 经过测试,如果是基本类型string、number、boolean,那么会变成相对应的构造函数String,Number,Boolean
162
+ // 如果只是指定了interface类型,那么会变成Object构造函数
114
163
 
115
- Reflect.defineMetadata(SERVICE_PARAM_TYPES, types, target); // 标记这个类可以注入
164
+ var types = Reflect.getMetadata(DECORATOR_KEYS.DESIGN_PARAM_TYPES, target) || []; // 存储构造函数的类型信息
165
+ // 这里只是转存了一下数据,并没有特殊逻辑
116
166
 
117
- Reflect.defineMetadata(DECORATOR_KEYS.INJECTABLE, true, target);
167
+ Reflect.defineMetadata(DECORATOR_KEYS.SERVICE_PARAM_TYPES, types, target);
118
168
  return target;
119
169
  };
120
170
  }
@@ -146,6 +196,122 @@ function resolveForwardRef(type) {
146
196
  return isForwardRef(type) ? type() : type;
147
197
  }
148
198
 
199
+ var CircularDependencyError = /*#__PURE__*/function (_Error) {
200
+ _inherits(CircularDependencyError, _Error);
201
+
202
+ var _super = _createSuper(CircularDependencyError);
203
+
204
+ function CircularDependencyError(provider, options) {
205
+ var _this;
206
+
207
+ _classCallCheck(this, CircularDependencyError);
208
+
209
+ _this = _super.call(this);
210
+
211
+ _defineProperty(_assertThisInitialized(_this), "name", 'CIRCULAR_DEPENDENCY_ERROR');
212
+
213
+ _defineProperty(_assertThisInitialized(_this), "message", _this.name);
214
+
215
+ var tokenArr = [provider.provide];
216
+ var currentProvider = options === null || options === void 0 ? void 0 : options.provider;
217
+
218
+ while (currentProvider && currentProvider.provide) {
219
+ tokenArr.push(currentProvider.provide);
220
+ currentProvider = currentProvider.parent;
221
+ }
222
+
223
+ var tokenListText = tokenArr.join(' <-- ');
224
+ _this.message = "CIRCULAR DEPENDENCY DETECTED. PLEASE FIX IT MANUALLY. \n ".concat(tokenListText);
225
+ return _this;
226
+ }
227
+
228
+ return CircularDependencyError;
229
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
230
+
231
+ var InjectFailedError = /*#__PURE__*/function (_Error2) {
232
+ _inherits(InjectFailedError, _Error2);
233
+
234
+ var _super2 = _createSuper(InjectFailedError);
235
+
236
+ function InjectFailedError(injectMeta, ClassName, key, paramType) {
237
+ var _this2;
238
+
239
+ _classCallCheck(this, InjectFailedError);
240
+
241
+ _this2 = _super2.call(this);
242
+
243
+ _defineProperty(_assertThisInitialized(_this2), "name", 'INJECT_FAILED_ERROR');
244
+
245
+ _defineProperty(_assertThisInitialized(_this2), "message", _this2.name);
246
+
247
+ if (paramType) {
248
+ // 是构造函数的参数装饰器
249
+ if (injectMeta && injectMeta.value === Object) {
250
+ _this2.message = "CAN NOT USE OBJECT AS INJECTION TOKEN. PARAMETER ".concat(key, " OF CLASS ").concat(ClassName, ".");
251
+ } else if (paramType === Object) {
252
+ _this2.message = "CONSTRUCTOR PARAMETER TYPE IS OBJECT OR INTERFACE, MUST USE @INJECT TO SPECIFY INJECTION TOKEN. PARAMETER ".concat(key, " OF CLASS ").concat(ClassName, ".");
253
+ }
254
+ } else {
255
+ // 是属性装饰器
256
+ if (!injectMeta) {
257
+ _this2.message = "INJECT PROPERTY REQUIRE @INJECT() DECORATOR. PROPERTY ".concat(key, " OF CLASS ").concat(ClassName, ".");
258
+ } else if (injectMeta.value === Object) {
259
+ _this2.message = "CAN NOT USE OBJECT AS INJECTION TOKEN. PROPERTY ".concat(key, " OF CLASS ").concat(ClassName, ".");
260
+ }
261
+ }
262
+
263
+ return _this2;
264
+ }
265
+
266
+ return InjectFailedError;
267
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
268
+
269
+ var ProviderNotValidError = /*#__PURE__*/function (_Error3) {
270
+ _inherits(ProviderNotValidError, _Error3);
271
+
272
+ var _super3 = _createSuper(ProviderNotValidError);
273
+
274
+ function ProviderNotValidError(provider) {
275
+ var _this3;
276
+
277
+ _classCallCheck(this, ProviderNotValidError);
278
+
279
+ _this3 = _super3.call(this);
280
+
281
+ _defineProperty(_assertThisInitialized(_this3), "name", 'PROVIDER_NOT_VALID_ERROR');
282
+
283
+ _defineProperty(_assertThisInitialized(_this3), "message", _this3.name);
284
+
285
+ _this3.message = "PROVIDER NOT VALID. ".concat(provider);
286
+ return _this3;
287
+ }
288
+
289
+ return ProviderNotValidError;
290
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
291
+
292
+ var TokenNotFoundError = /*#__PURE__*/function (_Error4) {
293
+ _inherits(TokenNotFoundError, _Error4);
294
+
295
+ var _super4 = _createSuper(TokenNotFoundError);
296
+
297
+ function TokenNotFoundError(token) {
298
+ var _this4;
299
+
300
+ _classCallCheck(this, TokenNotFoundError);
301
+
302
+ _this4 = _super4.call(this);
303
+
304
+ _defineProperty(_assertThisInitialized(_this4), "name", 'TOKEN_NOT_FOUND_ERROR');
305
+
306
+ _defineProperty(_assertThisInitialized(_this4), "message", _this4.name);
307
+
308
+ _this4.message = "TOKEN IS NOT A INJECTABLE CLASS OR SKIP OUT OF ROOT INJECTOR. YOU CAN USE @Optional DECORATOR TO IGNORE THIS ERROR IF THIS SERVICE IS OPTIONAL. ".concat(token);
309
+ return _this4;
310
+ }
311
+
312
+ return TokenNotFoundError;
313
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
314
+
149
315
  var NOOP = function NOOP(n) {
150
316
  return n;
151
317
  }; // 第一步:准备构造函数的依赖对象
@@ -162,24 +328,21 @@ var Injector = /*#__PURE__*/function () {
162
328
 
163
329
  _classCallCheck(this, Injector);
164
330
 
165
- _defineProperty(this, "providerMap", new Map());
166
-
167
- _defineProperty(this, "parentToken", null);
168
-
169
331
  _defineProperty(this, "parent", void 0);
170
332
 
171
- _defineProperty(this, "options", void 0);
333
+ _defineProperty(this, "providerMap", new Map());
334
+
335
+ _defineProperty(this, "beforeCacheHook", void 0);
172
336
 
173
- _defineProperty(this, "postHook", void 0);
337
+ _defineProperty(this, "mergePropertyHook", void 0);
174
338
 
175
- _defineProperty(this, "mergeHook", void 0);
339
+ // 引用父级Injector
340
+ this.parent = parent; // 在把服务实例放到缓存中之前,可以调用这个钩子让服务响应化
176
341
 
177
- this.parent = parent;
178
- this.options = options; // 在获取服务实例之后,在更新provider.useValue之前,使服务响应化
342
+ this.beforeCacheHook = options.beforeCacheHook || NOOP; // 在注入实例属性时,需要把属性merge到服务实例对象上,合并过程需要保持响应式
179
343
 
180
- this.postHook = options.postHook || NOOP;
181
- this.mergeHook = options.mergeHook || merge;
182
- this.resolveProviders(providers);
344
+ this.mergePropertyHook = options.mergePropertyHook || merge;
345
+ this.addProviders(providers);
183
346
  }
184
347
 
185
348
  _createClass(Injector, [{
@@ -187,102 +350,242 @@ var Injector = /*#__PURE__*/function () {
187
350
  value: function get(token) {
188
351
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
189
352
 
190
- if (options.self) {
353
+ if (options.skip) {
354
+ if (this.parent) {
355
+ return this.parent.get(token, _objectSpread(_objectSpread({}, options), {}, {
356
+ skip: false
357
+ }));
358
+ } else {
359
+ if (!options.optional) {
360
+ throw new TokenNotFoundError(token);
361
+ }
362
+ }
363
+ } else if (options.self) {
191
364
  if (this.providerMap.has(token)) {
192
365
  var provider = this.providerMap.get(token);
193
366
 
194
367
  if (provider.status === SERVICE_STATUS.INITING) {
195
- throw new Error("".concat(ERROR_CIRCULAR_DEPENDENCY, " ").concat(token, " and ").concat(this.parentToken, " depent on each other."));
368
+ throw new CircularDependencyError(provider, options);
196
369
  }
197
370
 
198
371
  return this.getServiceByProvider(provider, options);
199
372
  } else if (!this.parent && typeof token === 'function' && Reflect.getMetadata(DECORATOR_KEYS.INJECTABLE, token)) {
200
373
  // 如果当前Injector已经是根Injector
201
374
  // 就必须要考虑self的限制
202
- return this.getServiceByClass(token, token);
203
- } else {
204
- if (DECORATOR_KEYS.OPTIONAL in options || DECORATOR_KEYS.DEFAULT_VALUE in options) {
205
- return options.defaultValue;
206
- } else {
207
- throw new Error("".concat(token, " ").concat(ERROR_TOKEN_NOT_FOUND));
208
- }
209
- }
210
- } else if (options.skip) {
211
- options.skip = false;
375
+ var _provider = this.getProviderByToken(token);
212
376
 
213
- if (this.parent) {
214
- return this.parent.get(token, options);
377
+ return this.getServiceByProvider(_provider, options);
215
378
  } else {
216
- if (DECORATOR_KEYS.OPTIONAL in options || DECORATOR_KEYS.DEFAULT_VALUE in options) {
217
- return options.defaultValue;
218
- } else {
219
- throw new Error("".concat(token, " ").concat(ERROR_TOKEN_NOT_FOUND));
379
+ if (!options.optional) {
380
+ throw new TokenNotFoundError(token);
220
381
  }
221
382
  }
222
383
  } else if (this.providerMap.has(token)) {
223
- var _provider = this.providerMap.get(token);
384
+ var _provider2 = this.providerMap.get(token);
224
385
 
225
- if (_provider.status === SERVICE_STATUS.INITING) {
226
- throw new Error("".concat(ERROR_CIRCULAR_DEPENDENCY, " ").concat(token, " and ").concat(this.parentToken, " depent on each other."));
386
+ if (_provider2.status === SERVICE_STATUS.INITING) {
387
+ throw new CircularDependencyError(_provider2, options);
227
388
  }
228
389
 
229
- return this.getServiceByProvider(_provider, options);
390
+ return this.getServiceByProvider(_provider2, options);
230
391
  } else if (this.parent) {
231
392
  return this.parent.get(token, options);
232
393
  } else if (typeof token === 'function' && Reflect.getMetadata(DECORATOR_KEYS.INJECTABLE, token)) {
233
- return this.getServiceByClass(token, token);
394
+ var _provider3 = this.getProviderByToken(token);
395
+
396
+ return this.getServiceByProvider(_provider3, options);
234
397
  } else {
235
- if (DECORATOR_KEYS.OPTIONAL in options || DECORATOR_KEYS.DEFAULT_VALUE in options) {
236
- return options.defaultValue;
237
- } else {
238
- throw new Error("".concat(token, " ").concat(ERROR_TOKEN_NOT_FOUND));
398
+ if (!options.optional) {
399
+ throw new TokenNotFoundError(token);
239
400
  }
240
401
  }
241
402
  }
242
403
  /**
243
- * 获取构造函数的参数-返回数组
244
- * @done
404
+ * 如果token对应的provider不存在
405
+ * 那么就创建一个
406
+ * 调用该方法之前需要保证token对应的provider已经存在或者token本身是一个可注入的类
407
+ *
245
408
  * @param {*} token
246
409
  * @return {*}
247
410
  * @memberof Injector
248
411
  */
249
412
 
413
+ }, {
414
+ key: "getProviderByToken",
415
+ value: function getProviderByToken(token) {
416
+ if (!this.providerMap.has(token)) {
417
+ this.addProvider(token);
418
+ }
419
+
420
+ return this.providerMap.get(token);
421
+ }
422
+ /**
423
+ * 通过provider直接获取service实例
424
+ *
425
+ * @param {*} provider
426
+ * @param {*} options
427
+ * @return {*}
428
+ * @memberof Injector
429
+ */
430
+
431
+ }, {
432
+ key: "getServiceByProvider",
433
+ value: function getServiceByProvider(provider, options) {
434
+ if ('useCacheValue' in provider) {
435
+ return provider.useCacheValue;
436
+ } else if ('useValue' in provider) {
437
+ return this.getServiceUseValueWithProvider(provider);
438
+ } else if (provider.useClass) {
439
+ return this.getServiceUseClassWithProvider(provider, options);
440
+ } else if (provider.useExisting) {
441
+ return this.getServiceUseExistingWithProvider(provider, options);
442
+ } else if (provider.useFactory) {
443
+ return this.getServiceUseFactoryWithProvider(provider, options);
444
+ } else {
445
+ throw new ProviderNotValidError(provider);
446
+ }
447
+ }
448
+ /**
449
+ * 通过useValue获取服务实例
450
+ *
451
+ * @param {*} provider
452
+ * @return {*}
453
+ * @memberof Injector
454
+ */
455
+
456
+ }, {
457
+ key: "getServiceUseValueWithProvider",
458
+ value: function getServiceUseValueWithProvider(provider) {
459
+ var cacheValue = this.beforeCacheHook(provider.useValue);
460
+ provider.useCacheValue = cacheValue;
461
+ return cacheValue;
462
+ }
463
+ /**
464
+ * 通过useClass获取服务实例
465
+ *
466
+ * @param {*} provider
467
+ * @param {*} options
468
+ * @return {*}
469
+ * @memberof Injector
470
+ */
471
+
472
+ }, {
473
+ key: "getServiceUseClassWithProvider",
474
+ value: function getServiceUseClassWithProvider(provider, options) {
475
+ provider.parent = options.provider;
476
+ provider.status = SERVICE_STATUS.INITING;
477
+ var ClassName = provider.useClass;
478
+ var params = this.getContructorParameters(ClassName, provider);
479
+ var cacheValue = this.beforeCacheHook(_construct(ClassName, _toConsumableArray(params)));
480
+ provider.useCacheValue = cacheValue;
481
+ provider.status = SERVICE_STATUS.CONSTRUCTED;
482
+ var properties = this.getInjectProperties(ClassName, provider);
483
+ this.mergePropertyHook(cacheValue, properties);
484
+ provider.status = SERVICE_STATUS.MERGED;
485
+ provider.parent = void 0;
486
+ return cacheValue;
487
+ }
488
+ /**
489
+ * 通过useExisting获取服务实例
490
+ *
491
+ * @param {*} provider
492
+ * @param {*} options
493
+ * @return {*}
494
+ * @memberof Injector
495
+ */
496
+
497
+ }, {
498
+ key: "getServiceUseExistingWithProvider",
499
+ value: function getServiceUseExistingWithProvider(provider, options) {
500
+ provider.parent = options.provider;
501
+ provider.status = SERVICE_STATUS.INITING;
502
+ var cacheValue = this.get(provider.useExisting, _objectSpread(_objectSpread({}, options), {}, {
503
+ provider: provider
504
+ }));
505
+ provider.useCacheValue = cacheValue;
506
+ provider.status = SERVICE_STATUS.CONSTRUCTED;
507
+ provider.parent = void 0;
508
+ return cacheValue;
509
+ }
510
+ /**
511
+ * 通过useFactory获取服务实例
512
+ *
513
+ * @param {*} provider
514
+ * @param {*} options
515
+ * @return {*}
516
+ * @memberof Injector
517
+ */
518
+
519
+ }, {
520
+ key: "getServiceUseFactoryWithProvider",
521
+ value: function getServiceUseFactoryWithProvider(provider, options) {
522
+ var _this5 = this;
523
+
524
+ provider.parent = options.provider;
525
+ provider.status = SERVICE_STATUS.INITING;
526
+ var deps = provider.deps || [];
527
+ var args = deps.map(function (dep) {
528
+ return _this5.get(dep, {
529
+ provider: provider
530
+ });
531
+ });
532
+ var serviceValue = provider.useFactory.apply(provider, _toConsumableArray(args));
533
+ var cacheValue = this.beforeCacheHook(serviceValue);
534
+ provider.useCacheValue = cacheValue;
535
+ provider.status = SERVICE_STATUS.CONSTRUCTED;
536
+ provider.parent = void 0;
537
+ return cacheValue;
538
+ }
539
+ /**
540
+ * 获取构造函数的参数-返回数组
541
+ *
542
+ * @param {*} ClassName
543
+ * @param {*} provider
544
+ * @return {*}
545
+ * @memberof Injector
546
+ */
547
+
250
548
  }, {
251
549
  key: "getContructorParameters",
252
- value: function getContructorParameters(token) {
253
- var _this = this;
550
+ value: function getContructorParameters(ClassName, provider) {
551
+ var _this6 = this;
254
552
 
255
- var currentParentToken = this.parentToken;
256
- this.parentToken = token;
257
- var params = this.getContructorParametersMetas(token);
553
+ var params = this.getContructorParametersMetas(ClassName);
258
554
  var result = params.map(function (meta) {
259
- return _this.get(meta.key, meta.value);
555
+ return _this6.get(meta.key, _objectSpread(_objectSpread({}, meta.value), {}, {
556
+ provider: provider
557
+ }));
260
558
  });
261
- this.parentToken = currentParentToken;
262
559
  return result;
263
560
  }
264
561
  /**
265
562
  * 获取构造函数的参数的装饰器元数据
266
- * @done
267
- * @param {*} token
563
+ *
564
+ * @param {*} ClassName
268
565
  * @return {*}
269
566
  * @memberof Injector
270
567
  */
271
568
 
272
569
  }, {
273
570
  key: "getContructorParametersMetas",
274
- value: function getContructorParametersMetas(token) {
571
+ value: function getContructorParametersMetas(ClassName) {
275
572
  // 构造函数的参数的类型数据-原始数据-是一个数组
276
- var params = Reflect.getMetadata(SERVICE_PARAM_TYPES, token) || []; // 构造函数的参数的类型数据-通过@Inject等装饰器实现-是一个对象-key是数字-对应第几个参数的类型数据
573
+ var params = Reflect.getMetadata(DECORATOR_KEYS.SERVICE_PARAM_TYPES, ClassName) || []; // 构造函数的参数的类型数据-通过@Inject等装饰器实现-是一个对象-key是数字-对应第几个参数的类型数据
277
574
 
278
- var propertiesMetadatas = Reflect.getMetadata(SERVICE_INJECTED_PARAMS, token) || {};
575
+ var propertiesMetadatas = Reflect.getMetadata(DECORATOR_KEYS.SERVICE_INJECTED_PARAMS, ClassName) || {};
279
576
  return params.map(function (paramType, index) {
280
577
  // 查找当前index对应的参数有没有使用装饰器
281
- var propertyMetadatas = propertiesMetadatas[index] || []; // 查找装饰器列表中有没有@Inject
578
+ var propertyMetadatas = propertiesMetadatas[index] || []; // 查找装饰器列表中有没有@Inject装饰器的数据
282
579
 
283
- var ctor = propertyMetadatas.find(function (meta) {
580
+ var injectMeta = propertyMetadatas.find(function (meta) {
284
581
  return meta.key === DECORATOR_KEYS.INJECT;
285
- }); // 把装饰器列表收集为对象,并且排除掉@Inject
582
+ });
583
+
584
+ if (injectMeta && injectMeta.value === Object || !injectMeta && paramType === Object) {
585
+ // 构造函数的参数可以不使用@Inject,但是一定不能是interface
586
+ throw new InjectFailedError(injectMeta, ClassName, index, paramType);
587
+ } // 把装饰器列表收集为对象,并且排除掉@Inject
588
+
286
589
 
287
590
  var options = propertyMetadatas.reduce(function (acc, meta) {
288
591
  if (meta.key !== DECORATOR_KEYS.INJECT) {
@@ -292,67 +595,67 @@ var Injector = /*#__PURE__*/function () {
292
595
  return acc;
293
596
  }, {});
294
597
  return {
295
- key: resolveForwardRef(ctor && ctor.value) || paramType,
598
+ key: resolveForwardRef(injectMeta && injectMeta.value) || paramType,
296
599
  value: options
297
600
  };
298
601
  });
299
602
  }
300
603
  /**
301
604
  * 获取注入的实例属性-返回对象
302
- * @done
303
- * @param {*} token
605
+ *
606
+ * @param {*} ClassName
607
+ * @param {*} provider
304
608
  * @return {*}
305
609
  * @memberof Injector
306
610
  */
307
611
 
308
612
  }, {
309
613
  key: "getInjectProperties",
310
- value: function getInjectProperties(token) {
311
- var _this2 = this;
614
+ value: function getInjectProperties(ClassName, provider) {
615
+ var _this7 = this;
312
616
 
313
- var currentParentToken = this.parentToken;
314
- this.parentToken = token;
315
- var metas = this.getInjectPropertiesMetas(token);
617
+ var metas = this.getInjectPropertiesMetas(ClassName);
316
618
  var properties = {};
317
619
  metas.forEach(function (meta) {
318
620
  var _meta$value;
319
621
 
320
- var property = _this2.get(meta.provide, meta.value);
622
+ var property = _this7.get(meta.provide, _objectSpread(_objectSpread({}, meta.value), {}, {
623
+ provider: provider
624
+ }));
321
625
 
322
- if (!(property === undefined && (_meta$value = meta.value) !== null && _meta$value !== void 0 && _meta$value.optional)) {
323
- properties[meta.key] = _this2.get(meta.provide, meta.value);
626
+ if (!(property === void 0 && (_meta$value = meta.value) !== null && _meta$value !== void 0 && _meta$value.optional)) {
627
+ properties[meta.key] = property;
324
628
  }
325
629
  });
326
- this.parentToken = currentParentToken;
327
630
  return properties;
328
631
  }
329
632
  /**
330
633
  * 获取注入属性的装饰器数据
331
- * @done
332
- * @param {*} token
634
+ *
635
+ * @param {*} ClassName
333
636
  * @return {*}
334
637
  * @memberof Injector
335
638
  */
336
639
 
337
640
  }, {
338
641
  key: "getInjectPropertiesMetas",
339
- value: function getInjectPropertiesMetas(token) {
642
+ value: function getInjectPropertiesMetas(ClassName) {
340
643
  // 获取注入属性的metas-类型是Recors<string, Array>
341
- var propertiesMetadatas = Reflect.getMetadata(SERVICE_INJECTED_PROPS, token) || {};
644
+ var propertiesMetadatas = Reflect.getMetadata(DECORATOR_KEYS.SERVICE_INJECTED_PROPS, ClassName) || {};
342
645
  var propertiesMetas = [];
343
646
 
344
647
  for (var key in propertiesMetadatas) {
345
648
  if (has(propertiesMetadatas, key)) {
346
649
  // 当前key属性对应的所有的装饰器
347
- var propertyMetadatas = propertiesMetadatas[key] || []; // 当前key属性对应的@Inject
650
+ var propertyMetadatas = propertiesMetadatas[key]; // 当前key属性对应的@Inject装饰器的数据
348
651
 
349
- var ctor = propertyMetadatas.find(function (meta) {
652
+ var injectMeta = propertyMetadatas.find(function (meta) {
350
653
  return meta.key === DECORATOR_KEYS.INJECT;
351
654
  });
352
655
 
353
- if (!ctor) {
656
+ if (!injectMeta || injectMeta.value === Object) {
354
657
  // 属性一定要手动指定@Inject
355
- throw new Error(ERROR_INJECT_NOT_VALID);
658
+ throw new InjectFailedError(injectMeta, ClassName, key);
356
659
  }
357
660
 
358
661
  var options = propertyMetadatas.reduce(function (acc, meta) {
@@ -364,7 +667,7 @@ var Injector = /*#__PURE__*/function () {
364
667
  }, {});
365
668
  propertiesMetas.push({
366
669
  key: key,
367
- provide: resolveForwardRef(ctor.value),
670
+ provide: resolveForwardRef(injectMeta.value),
368
671
  value: options
369
672
  });
370
673
  }
@@ -372,103 +675,25 @@ var Injector = /*#__PURE__*/function () {
372
675
 
373
676
  return propertiesMetas;
374
677
  }
375
- /**
376
- * 通过provider直接获取service实例
377
- * @done
378
- * @param {*} provider
379
- * @param {*} options
380
- * @return {*}
381
- * @memberof Injector
382
- */
383
-
384
- }, {
385
- key: "getServiceByProvider",
386
- value: function getServiceByProvider(provider, options) {
387
- var _this3 = this;
388
-
389
- if ('useValue' in provider) {
390
- return provider.useValue;
391
- } else if (provider.useClass) {
392
- var serviceValue = this.getServiceByClass(provider.useClass, provider.provide);
393
- provider.useValue = this.postHook(serviceValue);
394
- return provider.useValue;
395
- } else if (provider.useExisting) {
396
- var _serviceValue = this.get(provider.useExisting, options);
397
-
398
- provider.useValue = this.postHook(_serviceValue);
399
- return provider.useValue;
400
- } else if (provider.useFactory) {
401
- var deps = provider.deps || [];
402
- var args = deps.map(function (dep) {
403
- return _this3.get(dep);
404
- });
405
-
406
- var _serviceValue2 = provider.useFactory.apply(provider, _toConsumableArray(args));
407
-
408
- provider.useValue = this.postHook(_serviceValue2);
409
- return provider.useValue;
410
- } else {
411
- throw new Error(ERROR_PROVIDER_NOT_VALID);
412
- }
413
- }
414
- /**
415
- * 通过类名获取服务实例
416
- * @done
417
- * @template T
418
- * @param {new (...args: any[]) => T} ClassName
419
- * @param {*} options
420
- * @return {*}
421
- * @memberof Injector
422
- */
423
-
424
- }, {
425
- key: "getServiceByClass",
426
- value: function getServiceByClass(ClassName, provide) {
427
- var provider = this.providerMap.get(provide);
428
-
429
- if (!provider) {
430
- this.addProvider({
431
- provide: provide,
432
- useClass: ClassName
433
- });
434
- provider = this.providerMap.get(provide);
435
- }
436
-
437
- provider.status = SERVICE_STATUS.INITING;
438
- var params = this.getContructorParameters(ClassName);
439
- var service = this.postHook(_construct(ClassName, _toConsumableArray(params)));
440
- provider.useValue = service;
441
- provider.status = SERVICE_STATUS.CONSTRUCTED;
442
- var properties = this.getInjectProperties(ClassName);
443
- this.mergeHook(service, properties);
444
- provider.status = SERVICE_STATUS.MERGED;
445
-
446
- if (service.onInit && typeof service.onInit === 'function') {
447
- service.onInit();
448
- }
449
-
450
- provider.status = SERVICE_STATUS.INITED;
451
- return service;
452
- }
453
678
  /**
454
679
  * 把providers数组转换成map,避免后续的遍历
455
- * @done
680
+ *
456
681
  * @param {any[]} providers
457
682
  * @memberof Injector
458
683
  */
459
684
 
460
685
  }, {
461
- key: "resolveProviders",
462
- value: function resolveProviders(providers) {
463
- var _this4 = this;
686
+ key: "addProviders",
687
+ value: function addProviders(providers) {
688
+ var _this8 = this;
464
689
 
465
690
  providers.forEach(function (provider) {
466
- _this4.addProvider(provider);
691
+ _this8.addProvider(provider);
467
692
  });
468
693
  }
469
694
  /**
470
695
  * 添加新的provider
471
- * @done
696
+ *
472
697
  * @param {*} provider
473
698
  * @memberof Injector
474
699
  */
@@ -477,10 +702,6 @@ var Injector = /*#__PURE__*/function () {
477
702
  key: "addProvider",
478
703
  value: function addProvider(provider) {
479
704
  if (provider.provide) {
480
- if ('useValue' in provider) {
481
- provider.useValue = this.postHook(provider.useValue);
482
- }
483
-
484
705
  this.providerMap.set(provider.provide, provider);
485
706
  } else {
486
707
  this.providerMap.set(provider, {
@@ -499,8 +720,12 @@ var Injector = /*#__PURE__*/function () {
499
720
  key: "dispose",
500
721
  value: function dispose() {
501
722
  this.providerMap.forEach(function (value) {
502
- if (value && value.dispose) {
503
- value.dispose();
723
+ if (value && value.useCacheValue && value.useCacheValue.dispose) {
724
+ try {
725
+ value.useCacheValue.dispose();
726
+ } catch (error) {
727
+ console.error(error);
728
+ }
504
729
  }
505
730
  });
506
731
  this.providerMap = null;
@@ -511,5 +736,5 @@ var Injector = /*#__PURE__*/function () {
511
736
  return Injector;
512
737
  }();
513
738
 
514
- export { DECORATOR_KEYS, DESIGN_PARAM_TYPES, ERROR_CIRCULAR_DEPENDENCY, ERROR_DISABLE_MULTIPLE_INJECTABLE, ERROR_INJECT_NOT_VALID, ERROR_PROVIDER_NOT_VALID, ERROR_TOKEN_NOT_FOUND, Inject, Injectable, Injector, Optional, SERVICE_INJECTED_PARAMS, SERVICE_INJECTED_PROPS, SERVICE_PARAM_TYPES, SERVICE_STATUS, Self, Skip, forwardRef, has, isForwardRef, merge, resolveForwardRef };
739
+ export { CircularDependencyError, DECORATOR_KEYS, Inject, InjectFailedError, Injectable, Injector, Optional, ProviderNotValidError, SERVICE_STATUS, Self, Skip, TokenNotFoundError, createDecorator, forwardRef, has, isForwardRef, merge, resolveForwardRef };
515
740
  //# sourceMappingURL=index.esm.runtime.js.map