@alterior/di 3.15.0 → 3.16.0

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 (41) hide show
  1. package/dist/injection/facade/errors.d.ts +1 -1
  2. package/dist/injection/facade/errors.d.ts.map +1 -1
  3. package/dist/injection/facade/errors.js +1 -1
  4. package/dist/injection/facade/errors.js.map +1 -1
  5. package/dist/injection/injector.js.map +1 -1
  6. package/dist/injection/metadata/annotations.d.ts.map +1 -1
  7. package/dist/injection/metadata/annotations.js.map +1 -1
  8. package/dist/injection/reflection/reflection_capabilities.d.ts.map +1 -1
  9. package/dist/injection/reflection/reflection_capabilities.js.map +1 -1
  10. package/dist/injection/reflective_injector.d.ts.map +1 -1
  11. package/dist/injection/reflective_injector.js +2 -3
  12. package/dist/injection/reflective_injector.js.map +1 -1
  13. package/dist/injection/reflective_injector.test.js.map +1 -1
  14. package/dist/modules.d.ts +2 -2
  15. package/dist/modules.d.ts.map +1 -1
  16. package/dist/modules.js +1 -1
  17. package/dist/modules.js.map +1 -1
  18. package/dist.esm/injection/facade/errors.d.ts +1 -1
  19. package/dist.esm/injection/facade/errors.d.ts.map +1 -1
  20. package/dist.esm/injection/facade/errors.js +1 -1
  21. package/dist.esm/injection/facade/errors.js.map +1 -1
  22. package/dist.esm/injection/injector.js.map +1 -1
  23. package/dist.esm/injection/metadata/annotations.d.ts.map +1 -1
  24. package/dist.esm/injection/metadata/annotations.js.map +1 -1
  25. package/dist.esm/injection/reflection/reflection_capabilities.d.ts.map +1 -1
  26. package/dist.esm/injection/reflection/reflection_capabilities.js.map +1 -1
  27. package/dist.esm/injection/reflective_injector.d.ts.map +1 -1
  28. package/dist.esm/injection/reflective_injector.js +2 -3
  29. package/dist.esm/injection/reflective_injector.js.map +1 -1
  30. package/dist.esm/injection/reflective_injector.test.js.map +1 -1
  31. package/dist.esm/modules.d.ts +2 -2
  32. package/dist.esm/modules.d.ts.map +1 -1
  33. package/dist.esm/modules.js +1 -1
  34. package/dist.esm/modules.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/injection/facade/errors.ts +1 -1
  37. package/src/injection/injector.ts +1 -1
  38. package/src/injection/metadata/annotations.ts +2 -2
  39. package/src/injection/reflection/reflection_capabilities.ts +162 -162
  40. package/src/injection/reflective_injector.ts +430 -431
  41. package/src/modules.ts +5 -5
@@ -13,10 +13,10 @@ import { Provider, ClassProvider, ProviderWithDependencies, isTypeProvider } fro
13
13
  import { cyclicDependencyError, instantiationError, noProviderError, outOfBoundsError } from './reflective_errors';
14
14
  import { ReflectiveKey } from './reflective_key';
15
15
  import {
16
- ReflectiveDependency,
17
- ResolvedReflectiveFactory,
18
- ResolvedReflectiveProvider,
19
- resolveReflectiveProviders,
16
+ ReflectiveDependency,
17
+ ResolvedReflectiveFactory,
18
+ ResolvedReflectiveProvider,
19
+ resolveReflectiveProviders,
20
20
  } from './reflective_provider';
21
21
  import { Annotation } from '@alterior/annotations';
22
22
 
@@ -59,489 +59,488 @@ const UNDEFINED = new Object();
59
59
  * @stable
60
60
  */
61
61
  export abstract class ReflectiveInjector implements Injector {
62
- /**
63
- * Turns an array of provider definitions into an array of resolved providers.
64
- *
65
- * A resolution is a process of flattening multiple nested arrays and converting individual
66
- * providers into an array of {@link ResolvedReflectiveProvider}s.
67
- *
68
- * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
69
- *
70
- * ```typescript
71
- * @Injectable()
72
- * class Engine {
73
- * }
74
- *
75
- * @Injectable()
76
- * class Car {
77
- * constructor(public engine:Engine) {}
78
- * }
79
- *
80
- * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
81
- *
82
- * expect(providers.length).toEqual(2);
83
- *
84
- * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
85
- * expect(providers[0].key.displayName).toBe("Car");
86
- * expect(providers[0].dependencies.length).toEqual(1);
87
- * expect(providers[0].factory).toBeDefined();
88
- *
89
- * expect(providers[1].key.displayName).toBe("Engine");
90
- * });
91
- * ```
92
- *
93
- * See {@link ReflectiveInjector#fromResolvedProviders} for more info.
94
- */
95
- static resolve(providers: Provider[]): ResolvedReflectiveProvider[] {
96
- return resolveReflectiveProviders(providers);
97
- }
98
-
99
- /**
100
- * Resolves an array of providers and creates an injector from those providers.
101
- *
102
- * The passed-in providers can be an array of `Type`, {@link Provider},
103
- * or a recursive array of more providers.
104
- *
105
- * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
106
- *
107
- * ```typescript
108
- * @Injectable()
109
- * class Engine {
110
- * }
111
- *
112
- * @Injectable()
113
- * class Car {
114
- * constructor(public engine:Engine) {}
115
- * }
116
- *
117
- * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
118
- * expect(injector.get(Car) instanceof Car).toBe(true);
119
- * ```
120
- *
121
- * This function is slower than the corresponding `fromResolvedProviders`
122
- * because it needs to resolve the passed-in providers first.
123
- * See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}.
124
- */
125
- static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector {
126
- const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
127
- return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
128
- }
129
-
130
- /**
131
- * Extract the dependencies of the given providers
132
- * @param providers
133
- */
134
- static reflectDependencies(provider : Provider): ProviderWithDependencies {
135
- if (isTypeProvider(provider)) {
136
- provider = {
137
- provide: provider,
138
- useClass: <ConcreteType<any>>provider
139
- };
62
+ /**
63
+ * Turns an array of provider definitions into an array of resolved providers.
64
+ *
65
+ * A resolution is a process of flattening multiple nested arrays and converting individual
66
+ * providers into an array of {@link ResolvedReflectiveProvider}s.
67
+ *
68
+ * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
69
+ *
70
+ * ```typescript
71
+ * @Injectable()
72
+ * class Engine {
73
+ * }
74
+ *
75
+ * @Injectable()
76
+ * class Car {
77
+ * constructor(public engine:Engine) {}
78
+ * }
79
+ *
80
+ * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
81
+ *
82
+ * expect(providers.length).toEqual(2);
83
+ *
84
+ * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
85
+ * expect(providers[0].key.displayName).toBe("Car");
86
+ * expect(providers[0].dependencies.length).toEqual(1);
87
+ * expect(providers[0].factory).toBeDefined();
88
+ *
89
+ * expect(providers[1].key.displayName).toBe("Engine");
90
+ * });
91
+ * ```
92
+ *
93
+ * See {@link ReflectiveInjector#fromResolvedProviders} for more info.
94
+ */
95
+ static resolve(providers: Provider[]): ResolvedReflectiveProvider[] {
96
+ return resolveReflectiveProviders(providers);
140
97
  }
141
98
 
142
- if (!provider['useClass'])
143
- return provider;
144
-
145
- let classProvider : ClassProvider = <any>provider;
146
-
147
- const paramsAnnotations = Annotation.getAllForConstructorParameters(classProvider.useClass);
148
- let params = Reflect.getOwnMetadata('design:paramtypes', classProvider.useClass);
149
- let deps = [];
150
-
151
- if (classProvider.useClass.length > 0 && typeof params === 'undefined') {
152
- throw new Error(
153
- `missing-reflection: No reflection metadata available `
154
- + `for ${classProvider.useClass.name}`
155
- );
99
+ /**
100
+ * Resolves an array of providers and creates an injector from those providers.
101
+ *
102
+ * The passed-in providers can be an array of `Type`, {@link Provider},
103
+ * or a recursive array of more providers.
104
+ *
105
+ * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
106
+ *
107
+ * ```typescript
108
+ * @Injectable()
109
+ * class Engine {
110
+ * }
111
+ *
112
+ * @Injectable()
113
+ * class Car {
114
+ * constructor(public engine:Engine) {}
115
+ * }
116
+ *
117
+ * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
118
+ * expect(injector.get(Car) instanceof Car).toBe(true);
119
+ * ```
120
+ *
121
+ * This function is slower than the corresponding `fromResolvedProviders`
122
+ * because it needs to resolve the passed-in providers first.
123
+ * See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}.
124
+ */
125
+ static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector {
126
+ const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
127
+ return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
156
128
  }
157
129
 
158
- if (params && params.length > 0) {
159
- for (let i = 0; i < params.length; ++i) {
160
- let param = params[i];
161
- let paramAnnotations = paramsAnnotations[i] || [];
130
+ /**
131
+ * Extract the dependencies of the given providers
132
+ * @param providers
133
+ */
134
+ static reflectDependencies(provider: Provider): ProviderWithDependencies {
135
+ if (isTypeProvider(provider)) {
136
+ provider = {
137
+ provide: provider,
138
+ useClass: <ConcreteType<any>>provider
139
+ };
140
+ }
141
+
142
+ if ('useClass' in provider)
143
+ return provider;
162
144
 
163
- let injectAnnotation = <InjectAnnotation>paramAnnotations.find(x => x instanceof InjectAnnotation);
164
- let optionalAnnotation = <OptionalAnnotation>paramAnnotations.find(x => x instanceof OptionalAnnotation);
145
+ let classProvider: ClassProvider = <any>provider;
165
146
 
166
- let token = param;
147
+ const paramsAnnotations = Annotation.getAllForConstructorParameters(classProvider.useClass);
148
+ let params = Reflect.getOwnMetadata('design:paramtypes', classProvider.useClass);
149
+ let deps = [];
167
150
 
168
- if (injectAnnotation) {
169
- token = injectAnnotation.token;
151
+ if (classProvider.useClass.length > 0 && typeof params === 'undefined') {
152
+ throw new Error(
153
+ `missing-reflection: No reflection metadata available `
154
+ + `for ${classProvider.useClass.name}`
155
+ );
170
156
  }
171
157
 
172
- let dep : any = token;
158
+ if (params && params.length > 0) {
159
+ for (let i = 0; i < params.length; ++i) {
160
+ let param = params[i];
161
+ let paramAnnotations = paramsAnnotations[i] || [];
173
162
 
174
- if (optionalAnnotation) {
175
- dep = [ Optional, token ];
176
- } else {
177
- dep = token;
163
+ let injectAnnotation = <InjectAnnotation>paramAnnotations.find(x => x instanceof InjectAnnotation);
164
+ let optionalAnnotation = <OptionalAnnotation>paramAnnotations.find(x => x instanceof OptionalAnnotation);
165
+
166
+ let token = param;
167
+
168
+ if (injectAnnotation) {
169
+ token = injectAnnotation.token;
170
+ }
171
+
172
+ let dep: any = token;
173
+
174
+ if (optionalAnnotation) {
175
+ dep = [Optional, token];
176
+ } else {
177
+ dep = token;
178
+ }
179
+
180
+ deps.push(dep);
181
+ }
178
182
  }
179
183
 
180
- deps.push(dep);
181
- }
184
+ return <ProviderWithDependencies>{
185
+ provide: classProvider.provide,
186
+ useClass: classProvider.useClass,
187
+ deps
188
+ }
182
189
  }
183
190
 
184
- return <ProviderWithDependencies>{
185
- provide: classProvider.provide,
186
- useClass: classProvider.useClass,
187
- deps
191
+ /**
192
+ * Creates an injector from previously resolved providers.
193
+ *
194
+ * This API is the recommended way to construct injectors in performance-sensitive parts.
195
+ *
196
+ * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
197
+ *
198
+ * ```typescript
199
+ * @Injectable()
200
+ * class Engine {
201
+ * }
202
+ *
203
+ * @Injectable()
204
+ * class Car {
205
+ * constructor(public engine:Engine) {}
206
+ * }
207
+ *
208
+ * var providers = ReflectiveInjector.resolve([Car, Engine]);
209
+ * var injector = ReflectiveInjector.fromResolvedProviders(providers);
210
+ * expect(injector.get(Car) instanceof Car).toBe(true);
211
+ * ```
212
+ * @experimental
213
+ */
214
+ static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector): ReflectiveInjector {
215
+ // tslint:disable-next-line:no-use-before-declare
216
+ return new ReflectiveInjector_(providers, parent);
188
217
  }
189
- }
190
-
191
- /**
192
- * Creates an injector from previously resolved providers.
193
- *
194
- * This API is the recommended way to construct injectors in performance-sensitive parts.
195
- *
196
- * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
197
- *
198
- * ```typescript
199
- * @Injectable()
200
- * class Engine {
201
- * }
202
- *
203
- * @Injectable()
204
- * class Car {
205
- * constructor(public engine:Engine) {}
206
- * }
207
- *
208
- * var providers = ReflectiveInjector.resolve([Car, Engine]);
209
- * var injector = ReflectiveInjector.fromResolvedProviders(providers);
210
- * expect(injector.get(Car) instanceof Car).toBe(true);
211
- * ```
212
- * @experimental
213
- */
214
- static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector): ReflectiveInjector {
215
- // tslint:disable-next-line:no-use-before-declare
216
- return new ReflectiveInjector_(providers, parent);
217
- }
218
-
219
- /**
220
- * Parent of this injector.
221
- *
222
- * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
223
- * -->
224
- *
225
- * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
226
- *
227
- * ```typescript
228
- * var parent = ReflectiveInjector.resolveAndCreate([]);
229
- * var child = parent.resolveAndCreateChild([]);
230
- * expect(child.parent).toBe(parent);
231
- * ```
232
- */
233
- abstract get parent(): Injector | null;
234
-
235
- /**
236
- * Resolves an array of providers and creates a child injector from those providers.
237
- *
238
- * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
239
- * -->
240
- *
241
- * The passed-in providers can be an array of `Type`, {@link Provider},
242
- * or a recursive array of more providers.
243
- *
244
- * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
245
- *
246
- * ```typescript
247
- * class ParentProvider {}
248
- * class ChildProvider {}
249
- *
250
- * var parent = ReflectiveInjector.resolveAndCreate([ParentProvider]);
251
- * var child = parent.resolveAndCreateChild([ChildProvider]);
252
- *
253
- * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
254
- * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
255
- * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
256
- * ```
257
- *
258
- * This function is slower than the corresponding `createChildFromResolved`
259
- * because it needs to resolve the passed-in providers first.
260
- * See {@link Injector#resolve} and {@link Injector#createChildFromResolved}.
261
- */
262
- abstract resolveAndCreateChild(providers: Provider[]): ReflectiveInjector;
263
-
264
- /**
265
- * Creates a child injector from previously resolved providers.
266
- *
267
- * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
268
- * -->
269
- *
270
- * This API is the recommended way to construct injectors in performance-sensitive parts.
271
- *
272
- * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
273
- *
274
- * ```typescript
275
- * class ParentProvider {}
276
- * class ChildProvider {}
277
- *
278
- * var parentProviders = ReflectiveInjector.resolve([ParentProvider]);
279
- * var childProviders = ReflectiveInjector.resolve([ChildProvider]);
280
- *
281
- * var parent = ReflectiveInjector.fromResolvedProviders(parentProviders);
282
- * var child = parent.createChildFromResolved(childProviders);
283
- *
284
- * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
285
- * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
286
- * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
287
- * ```
288
- */
289
- abstract createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector;
290
-
291
- /**
292
- * Resolves a provider and instantiates an object in the context of the injector.
293
- *
294
- * The created object does not get cached by the injector.
295
- *
296
- * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
297
- *
298
- * ```typescript
299
- * @Injectable()
300
- * class Engine {
301
- * }
302
- *
303
- * @Injectable()
304
- * class Car {
305
- * constructor(public engine:Engine) {}
306
- * }
307
- *
308
- * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
309
- *
310
- * var car = injector.resolveAndInstantiate(Car);
311
- * expect(car.engine).toBe(injector.get(Engine));
312
- * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
313
- * ```
314
- */
315
- abstract resolveAndInstantiate(provider: Provider): any;
316
-
317
- /**
318
- * Instantiates an object using a resolved provider in the context of the injector.
319
- *
320
- * The created object does not get cached by the injector.
321
- *
322
- * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
323
- *
324
- * ```typescript
325
- * @Injectable()
326
- * class Engine {
327
- * }
328
- *
329
- * @Injectable()
330
- * class Car {
331
- * constructor(public engine:Engine) {}
332
- * }
333
- *
334
- * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
335
- * var carProvider = ReflectiveInjector.resolve([Car])[0];
336
- * var car = injector.instantiateResolved(carProvider);
337
- * expect(car.engine).toBe(injector.get(Engine));
338
- * expect(car).not.toBe(injector.instantiateResolved(carProvider));
339
- * ```
340
- */
341
- abstract instantiateResolved(provider: ResolvedReflectiveProvider): any;
342
-
343
- abstract get(token: any, notFoundValue?: any): any;
218
+
219
+ /**
220
+ * Parent of this injector.
221
+ *
222
+ * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
223
+ * -->
224
+ *
225
+ * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
226
+ *
227
+ * ```typescript
228
+ * var parent = ReflectiveInjector.resolveAndCreate([]);
229
+ * var child = parent.resolveAndCreateChild([]);
230
+ * expect(child.parent).toBe(parent);
231
+ * ```
232
+ */
233
+ abstract get parent(): Injector | null;
234
+
235
+ /**
236
+ * Resolves an array of providers and creates a child injector from those providers.
237
+ *
238
+ * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
239
+ * -->
240
+ *
241
+ * The passed-in providers can be an array of `Type`, {@link Provider},
242
+ * or a recursive array of more providers.
243
+ *
244
+ * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
245
+ *
246
+ * ```typescript
247
+ * class ParentProvider {}
248
+ * class ChildProvider {}
249
+ *
250
+ * var parent = ReflectiveInjector.resolveAndCreate([ParentProvider]);
251
+ * var child = parent.resolveAndCreateChild([ChildProvider]);
252
+ *
253
+ * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
254
+ * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
255
+ * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
256
+ * ```
257
+ *
258
+ * This function is slower than the corresponding `createChildFromResolved`
259
+ * because it needs to resolve the passed-in providers first.
260
+ * See {@link Injector#resolve} and {@link Injector#createChildFromResolved}.
261
+ */
262
+ abstract resolveAndCreateChild(providers: Provider[]): ReflectiveInjector;
263
+
264
+ /**
265
+ * Creates a child injector from previously resolved providers.
266
+ *
267
+ * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
268
+ * -->
269
+ *
270
+ * This API is the recommended way to construct injectors in performance-sensitive parts.
271
+ *
272
+ * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
273
+ *
274
+ * ```typescript
275
+ * class ParentProvider {}
276
+ * class ChildProvider {}
277
+ *
278
+ * var parentProviders = ReflectiveInjector.resolve([ParentProvider]);
279
+ * var childProviders = ReflectiveInjector.resolve([ChildProvider]);
280
+ *
281
+ * var parent = ReflectiveInjector.fromResolvedProviders(parentProviders);
282
+ * var child = parent.createChildFromResolved(childProviders);
283
+ *
284
+ * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
285
+ * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
286
+ * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
287
+ * ```
288
+ */
289
+ abstract createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector;
290
+
291
+ /**
292
+ * Resolves a provider and instantiates an object in the context of the injector.
293
+ *
294
+ * The created object does not get cached by the injector.
295
+ *
296
+ * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
297
+ *
298
+ * ```typescript
299
+ * @Injectable()
300
+ * class Engine {
301
+ * }
302
+ *
303
+ * @Injectable()
304
+ * class Car {
305
+ * constructor(public engine:Engine) {}
306
+ * }
307
+ *
308
+ * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
309
+ *
310
+ * var car = injector.resolveAndInstantiate(Car);
311
+ * expect(car.engine).toBe(injector.get(Engine));
312
+ * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
313
+ * ```
314
+ */
315
+ abstract resolveAndInstantiate(provider: Provider): any;
316
+
317
+ /**
318
+ * Instantiates an object using a resolved provider in the context of the injector.
319
+ *
320
+ * The created object does not get cached by the injector.
321
+ *
322
+ * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
323
+ *
324
+ * ```typescript
325
+ * @Injectable()
326
+ * class Engine {
327
+ * }
328
+ *
329
+ * @Injectable()
330
+ * class Car {
331
+ * constructor(public engine:Engine) {}
332
+ * }
333
+ *
334
+ * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
335
+ * var carProvider = ReflectiveInjector.resolve([Car])[0];
336
+ * var car = injector.instantiateResolved(carProvider);
337
+ * expect(car.engine).toBe(injector.get(Engine));
338
+ * expect(car).not.toBe(injector.instantiateResolved(carProvider));
339
+ * ```
340
+ */
341
+ abstract instantiateResolved(provider: ResolvedReflectiveProvider): any;
342
+
343
+ abstract get(token: any, notFoundValue?: any): any;
344
344
  }
345
345
 
346
346
  // tslint:disable-next-line:class-name
347
347
  export class ReflectiveInjector_ implements ReflectiveInjector {
348
- /** @internal */
349
- _constructionCounter: number = 0;
350
- /** @internal */
351
- public _providers: ResolvedReflectiveProvider[];
352
- /** @internal */
353
- public _parent: Injector | null;
354
-
355
- keyIds: number[];
356
- objs: any[];
357
- /**
358
- * Private
359
- */
360
- constructor(_providers: ResolvedReflectiveProvider[], _parent?: Injector) {
361
- this._providers = _providers;
362
- this._parent = _parent || null;
363
-
364
- const len = _providers.length;
365
-
366
- this.keyIds = new Array(len);
367
- this.objs = new Array(len);
368
-
369
- for (let i = 0; i < len; i++) {
370
- this.keyIds[i] = _providers[i].key.id;
371
- this.objs[i] = UNDEFINED;
348
+ /** @internal */
349
+ _constructionCounter: number = 0;
350
+ /** @internal */
351
+ public _providers: ResolvedReflectiveProvider[];
352
+ /** @internal */
353
+ public _parent: Injector | null;
354
+
355
+ keyIds: number[];
356
+ objs: any[];
357
+ /**
358
+ * Private
359
+ */
360
+ constructor(_providers: ResolvedReflectiveProvider[], _parent?: Injector) {
361
+ this._providers = _providers;
362
+ this._parent = _parent || null;
363
+
364
+ const len = _providers.length;
365
+
366
+ this.keyIds = new Array(len);
367
+ this.objs = new Array(len);
368
+
369
+ for (let i = 0; i < len; i++) {
370
+ this.keyIds[i] = _providers[i].key.id;
371
+ this.objs[i] = UNDEFINED;
372
+ }
372
373
  }
373
- }
374
-
375
- private _useSelf = new SelfAnnotation();
376
374
 
377
- get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND, options?: InjectorGetOptions): any {
378
- return this._getByKey(ReflectiveKey.get(token), options?.self ? this._useSelf: null, notFoundValue);
379
- }
375
+ private _useSelf = new SelfAnnotation();
380
376
 
381
- get parent(): Injector | null {
382
- return this._parent;
383
- }
377
+ get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND, options?: InjectorGetOptions): any {
378
+ return this._getByKey(ReflectiveKey.get(token), options?.self ? this._useSelf : null, notFoundValue);
379
+ }
384
380
 
385
- resolveAndCreateChild(providers: Provider[]): ReflectiveInjector {
386
- const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
387
- return this.createChildFromResolved(ResolvedReflectiveProviders);
388
- }
381
+ get parent(): Injector | null {
382
+ return this._parent;
383
+ }
389
384
 
390
- createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector {
391
- const inj = new ReflectiveInjector_(providers);
392
- inj._parent = this;
393
- return inj;
394
- }
385
+ resolveAndCreateChild(providers: Provider[]): ReflectiveInjector {
386
+ const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
387
+ return this.createChildFromResolved(ResolvedReflectiveProviders);
388
+ }
395
389
 
396
- resolveAndInstantiate(provider: Provider): any {
397
- return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
398
- }
390
+ createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector {
391
+ const inj = new ReflectiveInjector_(providers);
392
+ inj._parent = this;
393
+ return inj;
394
+ }
399
395
 
400
- instantiateResolved(provider: ResolvedReflectiveProvider): any {
401
- return this._instantiateProvider(provider);
402
- }
396
+ resolveAndInstantiate(provider: Provider): any {
397
+ return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
398
+ }
403
399
 
404
- getProviderAtIndex(index: number): ResolvedReflectiveProvider {
405
- if (index < 0 || index >= this._providers.length) {
406
- throw outOfBoundsError(index);
400
+ instantiateResolved(provider: ResolvedReflectiveProvider): any {
401
+ return this._instantiateProvider(provider);
407
402
  }
408
- return this._providers[index];
409
- }
410
403
 
411
- /** @internal */
412
- _new(provider: ResolvedReflectiveProvider): any {
413
- if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
414
- throw cyclicDependencyError(this, provider.key);
404
+ getProviderAtIndex(index: number): ResolvedReflectiveProvider {
405
+ if (index < 0 || index >= this._providers.length) {
406
+ throw outOfBoundsError(index);
407
+ }
408
+ return this._providers[index];
415
409
  }
416
- return this._instantiateProvider(provider);
417
- }
418
-
419
- private _getMaxNumberOfObjects(): number {
420
- return this.objs.length;
421
- }
422
-
423
- private _instantiateProvider(provider: ResolvedReflectiveProvider): any {
424
- if (provider.multiProvider) {
425
- const res = new Array(provider.resolvedFactories.length);
426
- for (let i = 0; i < provider.resolvedFactories.length; ++i) {
427
- res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
428
- }
429
- return res;
430
- } else {
431
- return this._instantiate(provider, provider.resolvedFactories[0]);
410
+
411
+ /** @internal */
412
+ _new(provider: ResolvedReflectiveProvider): any {
413
+ if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
414
+ throw cyclicDependencyError(this, provider.key);
415
+ }
416
+ return this._instantiateProvider(provider);
432
417
  }
433
- }
434
-
435
- private _instantiate(provider: ResolvedReflectiveProvider, ResolvedReflectiveFactory: ResolvedReflectiveFactory): any {
436
- const factory = ResolvedReflectiveFactory.factory;
437
-
438
- let deps: any[];
439
- try {
440
- deps = ResolvedReflectiveFactory.dependencies.map(dep => this._getByReflectiveDependency(dep));
441
- } catch (e) {
442
- if (e.addKey) {
443
- e.addKey(this, provider.key);
444
- }
445
- throw e;
418
+
419
+ private _getMaxNumberOfObjects(): number {
420
+ return this.objs.length;
446
421
  }
447
422
 
448
- let obj: any;
449
- try {
450
- Injector.run(this, () => {
451
- obj = factory(...deps);
452
- });
453
- } catch (e) {
454
- throw instantiationError(this, e, e.stack, provider.key);
423
+ private _instantiateProvider(provider: ResolvedReflectiveProvider): any {
424
+ if (provider.multiProvider) {
425
+ const res = new Array(provider.resolvedFactories.length);
426
+ for (let i = 0; i < provider.resolvedFactories.length; ++i) {
427
+ res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
428
+ }
429
+ return res;
430
+ } else {
431
+ return this._instantiate(provider, provider.resolvedFactories[0]);
432
+ }
455
433
  }
456
434
 
457
- return obj;
458
- }
435
+ private _instantiate(provider: ResolvedReflectiveProvider, ResolvedReflectiveFactory: ResolvedReflectiveFactory): any {
436
+ const factory = ResolvedReflectiveFactory.factory;
437
+
438
+ let deps: any[];
439
+ try {
440
+ deps = ResolvedReflectiveFactory.dependencies.map(dep => this._getByReflectiveDependency(dep));
441
+ } catch (e: any) {
442
+ if (e.addKey)
443
+ e.addKey(this, provider.key);
444
+ throw e;
445
+ }
459
446
 
460
- private _getByReflectiveDependency(dep: ReflectiveDependency): any {
461
- return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
462
- }
447
+ let obj: any;
448
+ try {
449
+ Injector.run(this, () => {
450
+ obj = factory(...deps);
451
+ });
452
+ } catch (e: any) {
453
+ throw instantiationError(this, e, e.stack, provider.key);
454
+ }
463
455
 
464
- private _getByKey(key: ReflectiveKey, visibility: SelfAnnotation | SkipSelfAnnotation | null, notFoundValue: any): any {
465
- // tslint:disable-next-line:no-use-before-declare
466
- if (key === INJECTOR_KEY) {
467
- return this;
456
+ return obj;
468
457
  }
469
458
 
470
- if (visibility instanceof SelfAnnotation) {
471
- return this._getByKeySelf(key, notFoundValue);
472
- } else {
473
- return this._getByKeyDefault(key, notFoundValue, visibility);
459
+ private _getByReflectiveDependency(dep: ReflectiveDependency): any {
460
+ return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
474
461
  }
475
- }
476
462
 
477
- private _getObjByKeyId(keyId: number): any {
478
- for (let i = 0; i < this.keyIds.length; i++) {
479
- if (this.keyIds[i] === keyId) {
480
- if (this.objs[i] === UNDEFINED) {
481
- this.objs[i] = this._new(this._providers[i]);
463
+ private _getByKey(key: ReflectiveKey, visibility: SelfAnnotation | SkipSelfAnnotation | null, notFoundValue: any): any {
464
+ // tslint:disable-next-line:no-use-before-declare
465
+ if (key === INJECTOR_KEY) {
466
+ return this;
482
467
  }
483
468
 
484
- return this.objs[i];
485
- }
469
+ if (visibility instanceof SelfAnnotation) {
470
+ return this._getByKeySelf(key, notFoundValue);
471
+ } else {
472
+ return this._getByKeyDefault(key, notFoundValue, visibility);
473
+ }
486
474
  }
487
475
 
488
- return UNDEFINED;
489
- }
476
+ private _getObjByKeyId(keyId: number): any {
477
+ for (let i = 0; i < this.keyIds.length; i++) {
478
+ if (this.keyIds[i] === keyId) {
479
+ if (this.objs[i] === UNDEFINED) {
480
+ this.objs[i] = this._new(this._providers[i]);
481
+ }
482
+
483
+ return this.objs[i];
484
+ }
485
+ }
490
486
 
491
- /** @internal */
492
- _throwOrNull(key: ReflectiveKey, notFoundValue: any): any {
493
- if (notFoundValue !== THROW_IF_NOT_FOUND) {
494
- return notFoundValue;
495
- } else {
496
- throw noProviderError(this, key);
487
+ return UNDEFINED;
497
488
  }
498
- }
499
-
500
- /** @internal */
501
- _getByKeySelf(key: ReflectiveKey, notFoundValue: any): any {
502
- const obj = this._getObjByKeyId(key.id);
503
- return obj !== UNDEFINED ? obj : this._throwOrNull(key, notFoundValue);
504
- }
505
-
506
- /** @internal */
507
- _getByKeyDefault(key: ReflectiveKey, notFoundValue: any, visibility: SelfAnnotation | SkipSelfAnnotation | null): any {
508
- let inj: Injector | null;
509
-
510
- if (visibility instanceof SkipSelfAnnotation) {
511
- inj = this._parent;
512
- } else {
513
- inj = this;
489
+
490
+ /** @internal */
491
+ _throwOrNull(key: ReflectiveKey, notFoundValue: any): any {
492
+ if (notFoundValue !== THROW_IF_NOT_FOUND) {
493
+ return notFoundValue;
494
+ } else {
495
+ throw noProviderError(this, key);
496
+ }
514
497
  }
515
498
 
516
- while (inj instanceof ReflectiveInjector_) {
517
- const inj_ = <ReflectiveInjector_>inj;
518
- const obj = inj_._getObjByKeyId(key.id);
519
- if (obj !== UNDEFINED) return obj;
520
- inj = inj_._parent;
499
+ /** @internal */
500
+ _getByKeySelf(key: ReflectiveKey, notFoundValue: any): any {
501
+ const obj = this._getObjByKeyId(key.id);
502
+ return obj !== UNDEFINED ? obj : this._throwOrNull(key, notFoundValue);
521
503
  }
522
- if (inj !== null) {
523
- return inj.get(key.token, notFoundValue);
524
- } else {
525
- return this._throwOrNull(key, notFoundValue);
504
+
505
+ /** @internal */
506
+ _getByKeyDefault(key: ReflectiveKey, notFoundValue: any, visibility: SelfAnnotation | SkipSelfAnnotation | null): any {
507
+ let inj: Injector | null;
508
+
509
+ if (visibility instanceof SkipSelfAnnotation) {
510
+ inj = this._parent;
511
+ } else {
512
+ inj = this;
513
+ }
514
+
515
+ while (inj instanceof ReflectiveInjector_) {
516
+ const inj_ = <ReflectiveInjector_>inj;
517
+ const obj = inj_._getObjByKeyId(key.id);
518
+ if (obj !== UNDEFINED) return obj;
519
+ inj = inj_._parent;
520
+ }
521
+ if (inj !== null) {
522
+ return inj.get(key.token, notFoundValue);
523
+ } else {
524
+ return this._throwOrNull(key, notFoundValue);
525
+ }
526
526
  }
527
- }
528
527
 
529
- get displayName(): string {
530
- const providers = _mapProviders(this, (b: ResolvedReflectiveProvider) => ' "' + b.key.displayName + '" ').join(', ');
531
- return `ReflectiveInjector(providers: [${providers}])`;
532
- }
528
+ get displayName(): string {
529
+ const providers = _mapProviders(this, (b: ResolvedReflectiveProvider) => ' "' + b.key.displayName + '" ').join(', ');
530
+ return `ReflectiveInjector(providers: [${providers}])`;
531
+ }
533
532
 
534
- toString(): string {
535
- return this.displayName;
536
- }
533
+ toString(): string {
534
+ return this.displayName;
535
+ }
537
536
  }
538
537
 
539
538
  const INJECTOR_KEY = ReflectiveKey.get(Injector);
540
539
 
541
540
  function _mapProviders(injector: ReflectiveInjector_, fn: Function): any[] {
542
- const res: any[] = new Array(injector._providers.length);
543
- for (let i = 0; i < injector._providers.length; ++i) {
544
- res[i] = fn(injector.getProviderAtIndex(i));
545
- }
546
- return res;
541
+ const res: any[] = new Array(injector._providers.length);
542
+ for (let i = 0; i < injector._providers.length; ++i) {
543
+ res[i] = fn(injector.getProviderAtIndex(i));
544
+ }
545
+ return res;
547
546
  }