async-injection 2.3.0 → 3.0.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 (45) hide show
  1. package/ReadMe.md +133 -194
  2. package/lib/async-factory-provider.d.ts +1 -1
  3. package/lib/bindable-provider.d.ts +2 -2
  4. package/lib/binding.d.ts +80 -0
  5. package/lib/cjs/async-factory-provider.js.map +1 -1
  6. package/lib/cjs/bindable-provider.js +5 -18
  7. package/lib/cjs/bindable-provider.js.map +1 -1
  8. package/lib/cjs/{binder.js → binding.js} +1 -1
  9. package/lib/cjs/binding.js.map +1 -0
  10. package/lib/cjs/class-provider.js +142 -39
  11. package/lib/cjs/class-provider.js.map +1 -1
  12. package/lib/cjs/container.js +62 -22
  13. package/lib/cjs/container.js.map +1 -1
  14. package/lib/cjs/decorators.js +61 -17
  15. package/lib/cjs/decorators.js.map +1 -1
  16. package/lib/cjs/index.js.map +1 -1
  17. package/lib/cjs/injector.js.map +1 -1
  18. package/lib/cjs/provider.js.map +1 -1
  19. package/lib/cjs/sync-factory-provider.js.map +1 -1
  20. package/lib/class-provider.d.ts +16 -2
  21. package/lib/container.d.ts +40 -14
  22. package/lib/decorators.d.ts +15 -2
  23. package/lib/esm/async-factory-provider.js.map +1 -1
  24. package/lib/esm/bindable-provider.js +5 -18
  25. package/lib/esm/bindable-provider.js.map +1 -1
  26. package/lib/esm/binding.js +2 -0
  27. package/lib/esm/binding.js.map +1 -0
  28. package/lib/esm/class-provider.js +143 -40
  29. package/lib/esm/class-provider.js.map +1 -1
  30. package/lib/esm/container.js +62 -22
  31. package/lib/esm/container.js.map +1 -1
  32. package/lib/esm/decorators.js +60 -18
  33. package/lib/esm/decorators.js.map +1 -1
  34. package/lib/esm/index.js.map +1 -1
  35. package/lib/esm/injector.js.map +1 -1
  36. package/lib/esm/provider.js.map +1 -1
  37. package/lib/esm/sync-factory-provider.js.map +1 -1
  38. package/lib/index.d.ts +1 -0
  39. package/lib/injector.d.ts +1 -1
  40. package/lib/sync-factory-provider.d.ts +1 -1
  41. package/package.json +1 -1
  42. package/lib/binder.d.ts +0 -110
  43. package/lib/cjs/binder.js.map +0 -1
  44. package/lib/esm/binder.js +0 -2
  45. package/lib/esm/binder.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/binding.ts"],"names":[],"mappings":"","sourcesContent":["import {ClassConstructor, InjectableId, Injector} from './injector';\n\n/**\n * Type definition for functions that return a value.\n * The function should return a valid value, but may throw an exception if it cannot.\n */\nexport type SyncFactory<T> = (injector: Injector) => T;\n\n/**\n * Type definition for functions that return a Promise for a value.\n * The function *must* not throw and must return a valid Promise (e.g. pending, resolved, rejected).\n */\nexport type AsyncFactory<T> = (injector: Injector) => Promise<T>;\n\n/**\n * You may bind an error handler which will be invoked if the bound InjectableId could not be put into service.\n * An error handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param injector The Injector that experienced the error.\n * @param id The identifier for what was trying to be made.\n * @param maker The thing that made (or tried to make) the value. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param error Identifies the problem that occurred.\n * @param value If the 'maker' was able to create the thing, but it had an error during post construction, the made thing will be passed here.\n * @returns one of 3 results...\n * A substitute thing (kind of like a 'maker' do-over) which must be fully operational (e.g. any `@PostConstruct` will be ignored).\n * An alternate Error which will be propagated back up the call chain.\n * Undefined, which means the 'error' parameter will be propagated back up the call chain.\n */\nexport type OnErrorCallback<T, M = unknown> = (injector: Injector, id: InjectableId<T>, maker: M, error: unknown, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param value The thing that was made.\n * @param injector The Injector that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M = unknown> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * Descriptor object used with {@link Container.register} to specify how an id should be bound.\n * Mirrors the TSyringe registration API.\n */\nexport type RegisterDescriptor<T> =\n\t| { useClass: ClassConstructor<T> }\n\t| { useValue: T }\n\t| { useFactory: SyncFactory<T> }\n\t| { useAsyncFactory: AsyncFactory<T> };\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M = unknown> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M = unknown> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M = unknown> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n"]}
@@ -1,6 +1,6 @@
1
1
  import { BindableProvider } from './bindable-provider.js';
2
2
  import { POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS } from './constants.js';
3
- import { _getInjectedIdAt, _getOptionalDefaultAt } from './decorators.js';
3
+ import { _getInjectedIdAt, _getInjectedIdForMethod, _getOptionalDefaultAt, _getOptionalDefaultForMethod } from './decorators.js';
4
4
  import { State } from './state.js';
5
5
  import { isPromise } from './utils.js';
6
6
  /**
@@ -27,64 +27,167 @@ export class ClassBasedProvider extends BindableProvider {
27
27
  }
28
28
  /**
29
29
  * @inheritDoc
30
- * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).
30
+ * This specialization returns undefined if 'asyncOnly' is true **and** there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous),
31
+ * **unless** the @PostConstruct method has injectable parameters, which may themselves require async resolution.
31
32
  */
32
33
  resolveIfSingleton(asyncOnly) {
33
- if ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))
34
+ if (!asyncOnly || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) || this.postConstructHasParams())
34
35
  return super.resolveIfSingleton(false);
35
36
  return undefined;
36
37
  }
37
38
  /**
38
- * Make a resolved or pending State that reflects any @PostConstruct annotations.
39
+ * Returns true if the @PostConstruct method (if any) has at least one parameter.
40
+ * Any parameter may require async resolution, so this class must participate in resolveSingletons.
41
+ */
42
+ postConstructHasParams() {
43
+ var _a;
44
+ const pcMethod = (_a = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, this.maker)) !== null && _a !== void 0 ? _a : Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker);
45
+ if (!pcMethod)
46
+ return false;
47
+ const paramTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker.prototype, pcMethod);
48
+ return Array.isArray(paramTypes) && paramTypes.length > 0;
49
+ }
50
+ /**
51
+ * Make a resolved or pending State that reflects any @PostConstruct annotations and/or onSuccess handler.
52
+ * Any @PostConstruct method (with any injected parameters) runs first; the onSuccess handler runs after.
39
53
  */
40
54
  makePostConstructState(obj) {
41
- var _a, _b;
42
- if (obj !== null && typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {
43
- let maybeAsync = false;
44
- let pcFn;
45
- if (typeof this.successHandler === 'function') {
46
- maybeAsync = true;
47
- pcFn = () => {
48
- return this.successHandler(obj, this.injector, this.id, this.maker);
49
- };
55
+ if (obj === null || typeof obj !== 'object' || Array.isArray(obj) || !obj.constructor) {
56
+ return State.MakeState(null, undefined, obj);
57
+ }
58
+ const ctor = obj.constructor;
59
+ // Look up the @PostConstruct method name (sync or async).
60
+ let pcMaybeAsync = false;
61
+ let pcMethodName = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor);
62
+ if (!pcMethodName) {
63
+ pcMethodName = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor);
64
+ pcMaybeAsync = !!pcMethodName;
65
+ }
66
+ const pcValid = !!(pcMethodName && typeof ctor.prototype[pcMethodName] === 'function');
67
+ const hasSuccess = typeof this.successHandler === 'function';
68
+ if (!pcValid && !hasSuccess) {
69
+ return State.MakeState(null, undefined, obj);
70
+ }
71
+ // Resolve any injectable parameters declared on the @PostConstruct method.
72
+ const paramStates = pcValid ? this.getMethodParameterStates(ctor, pcMethodName) : [];
73
+ // A synchronously rejected param (with no @Optional fallback) is treated as a PostConstruct error.
74
+ const firstRejected = paramStates.find(p => !p.pending && p.rejected);
75
+ if (firstRejected) {
76
+ try {
77
+ obj = this.queryErrorHandler(firstRejected.rejected, obj);
78
+ return State.MakeState(null, undefined, obj);
50
79
  }
51
- else {
52
- // Check to see if there is a @PostConstruct annotation on a method of the class.
53
- const ctor = obj.constructor;
54
- let postConstruct = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor);
55
- if (!postConstruct) {
56
- maybeAsync = true;
57
- postConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor);
58
- }
59
- if (postConstruct && ctor.prototype[postConstruct] && typeof ctor.prototype[postConstruct] === 'function')
60
- pcFn = (_b = (_a = obj[postConstruct]).bind) === null || _b === void 0 ? void 0 : _b.call(_a, obj);
80
+ catch (e) {
81
+ return State.MakeState(null, e, undefined);
61
82
  }
62
- if (pcFn) {
63
- let result;
83
+ }
84
+ if (paramStates.some(p => p.pending)) {
85
+ // One or more params require async resolution — wait for them, then invoke.
86
+ const paramsPromise = Promise.all(paramStates.map(async (p, idx) => {
87
+ if (p.pending) {
88
+ try {
89
+ return await p.promise;
90
+ }
91
+ catch (err) {
92
+ const md = _getOptionalDefaultForMethod(ctor.prototype, pcMethodName, idx);
93
+ if (!md)
94
+ throw err;
95
+ return md.value;
96
+ }
97
+ }
98
+ return p.fulfilled;
99
+ }));
100
+ return State.MakeState((async () => {
101
+ let args;
64
102
  try {
65
- result = pcFn();
103
+ args = await paramsPromise;
66
104
  }
67
105
  catch (err) {
68
- // The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.
69
- try {
70
- obj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.
71
- return State.MakeState(null, undefined, obj);
72
- }
73
- catch (e) {
74
- // could not recover, propagate the error.
75
- return State.MakeState(null, e, undefined);
106
+ return this.queryErrorHandler(err, obj);
107
+ }
108
+ try {
109
+ const pcResult = obj[pcMethodName](...args);
110
+ if (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise(pcResult))))
111
+ await pcResult;
112
+ if (hasSuccess) {
113
+ const sResult = this.successHandler(obj, this.injector, this.id, this.maker);
114
+ if (sResult && isPromise(sResult))
115
+ await sResult;
76
116
  }
117
+ return obj;
118
+ }
119
+ catch (err) {
120
+ return this.queryErrorHandler(err, obj);
77
121
  }
78
- // The post construction method says it will let us know when it's finished.
79
- if (result && (result instanceof Promise || (maybeAsync && isPromise(result)))) {
80
- // Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).
81
- return State.MakeState(this.makePromiseForObj(result, () => obj));
122
+ })());
123
+ }
124
+ // All params are synchronously available (or there are no params).
125
+ const pcArgs = paramStates.map(p => p.fulfilled);
126
+ const maybeAsync = pcMaybeAsync || hasSuccess;
127
+ // Build a single function that calls PostConstruct (with resolved args) then onSuccess.
128
+ let pcFn;
129
+ if (pcValid) {
130
+ pcFn = () => {
131
+ const pcResult = obj[pcMethodName](...pcArgs);
132
+ if (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise(pcResult)))) {
133
+ // PostConstruct is async — chain onSuccess after it resolves.
134
+ return hasSuccess
135
+ ? pcResult.then(() => this.successHandler(obj, this.injector, this.id, this.maker))
136
+ : pcResult;
82
137
  }
138
+ // PostConstruct is sync — call onSuccess immediately.
139
+ if (hasSuccess)
140
+ return this.successHandler(obj, this.injector, this.id, this.maker);
141
+ return pcResult;
142
+ };
143
+ }
144
+ else {
145
+ // No PostConstruct — just call onSuccess.
146
+ pcFn = () => this.successHandler(obj, this.injector, this.id, this.maker);
147
+ }
148
+ let result;
149
+ try {
150
+ result = pcFn();
151
+ }
152
+ catch (err) {
153
+ try {
154
+ obj = this.queryErrorHandler(err, obj);
155
+ return State.MakeState(null, undefined, obj);
83
156
  }
157
+ catch (e) {
158
+ return State.MakeState(null, e, undefined);
159
+ }
160
+ }
161
+ if (result && (result instanceof Promise || (maybeAsync && isPromise(result)))) {
162
+ return State.MakeState(this.makePromiseForObj(result, () => obj));
84
163
  }
85
- // No PostConstruct, just return a resolved State
86
164
  return State.MakeState(null, undefined, obj);
87
165
  }
166
+ /**
167
+ * Collects the resolved States for all injectable parameters of a @PostConstruct method.
168
+ * Uses the same resolution rules as constructor parameters: the reflected type (or an explicit @Inject token) is used to look up the binding, and an error is thrown if the type cannot be determined.
169
+ * Use @Optional() on a parameter to supply a fallback when no binding is found.
170
+ * Returns an empty array if the method has no parameters.
171
+ */
172
+ getMethodParameterStates(ctor, methodName) {
173
+ const argTypes = Reflect.getMetadata(REFLECT_PARAMS, ctor.prototype, methodName);
174
+ if (!Array.isArray(argTypes) || argTypes.length === 0)
175
+ return [];
176
+ return argTypes.map((argType, index) => {
177
+ const overrideToken = _getInjectedIdForMethod(ctor.prototype, methodName, index);
178
+ const actualToken = overrideToken !== undefined ? overrideToken : argType;
179
+ if (actualToken == null) {
180
+ throw new Error(`Injection error. Unable to determine parameter ${index} type/value of ${ctor.name}.${methodName}`);
181
+ }
182
+ let param = this.injector.resolveState(actualToken);
183
+ if (!param.pending && param.rejected) {
184
+ const optionalDefault = _getOptionalDefaultForMethod(ctor.prototype, methodName, index);
185
+ if (optionalDefault)
186
+ param = State.MakeState(null, undefined, optionalDefault.value);
187
+ }
188
+ return param;
189
+ });
190
+ }
88
191
  /**
89
192
  * This method collects the States of all the constructor parameters for our target class.
90
193
  */
@@ -162,7 +265,7 @@ export class ClassBasedProvider extends BindableProvider {
162
265
  return await state.promise; // chain (aka wait some more).
163
266
  }
164
267
  else if (state.rejected) {
165
- return state.rejected; // error
268
+ throw state.rejected; // error
166
269
  }
167
270
  else {
168
271
  return state.fulfilled; // value (aka obj).
@@ -1 +1 @@
1
- {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators';\nimport {ClassConstructor, InjectableId, Injector} from './injector';\nimport {State} from './state';\nimport {isPromise} from './utils';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (obj !== null && typeof obj === 'object' && (!Array.isArray(obj)) && (obj as any).constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: (() => void | Error | Promise<void | Error>) | undefined;\n\t\t\tif (typeof this.successHandler === 'function') {\n\t\t\t\tmaybeAsync = true;\n\t\t\t\tpcFn = () => {\n\t\t\t\t\treturn this.successHandler!(obj, this.injector, this.id, this.maker);\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tconst ctor = (obj as any).constructor;\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor) as string;\n\t\t\t\tif (!postConstruct) {\n\t\t\t\t\tmaybeAsync = true;\n\t\t\t\t\tpostConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor) as string;\n\t\t\t\t}\n\t\t\t\tif (postConstruct && ctor.prototype[postConstruct] && typeof ctor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = (obj as any)[postConstruct].bind?.(obj);\n\n\t\t\t}\n\t\t\tif (pcFn) {\n\t\t\t\tlet result: any;\n\t\t\t\ttry {\n\t\t\t\t\tresult = pcFn();\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\t// The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.\n\t\t\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The post construction method says it will let us know when it's finished.\n\t\t\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\t\t\t// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).\n\t\t\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies returning undefined instead.\n\t\t\t// Additionally, it cannot return generic types (no runtime type info).\n\t\t\t// If an Inject annotation precedes the parameter, then that is what should get injected.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\t// If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\tif (actualToken === undefined) {\n\t\t\t\t// No Inject annotation, and the type is not known.\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);\n\t\t\t}\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst firstRejectedParam = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (firstRejectedParam)\n\t\t\treturn firstRejectedParam as State<T>;\n\t\tif (params.some(p => p.pending)) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\t// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.\n\t\t\t// This might create some unnecessary (but immediately resolved) Promise objects,\n\t\t\t// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(params.map(async (p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await p.promise!;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t// This was a promised param that failed to resolve.\n\t\t\t\t\t\t// If there is an Optional decorator, use that, otherwise, failure is failure.\n\t\t\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, idx);\n\t\t\t\t\t\tif (!md)\n\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\treturn md.value as unknown;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn p.fulfilled;\n\t\t\t})), (values) => {\n\t\t\t\tif (values) {\n\t\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\t\treturn Reflect.construct(this.maker, values);\n\t\t\t\t}\n\t\t\t\treturn undefined as unknown as T;\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>((async () => {\n\t\t\t\tconst obj = await objPromise;\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn await state.promise!; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\treturn state.rejected as any; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled!; // value (aka obj).\n\t\t\t\t}\n\t\t\t})());\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants';\nimport {_getInjectedIdAt, _getInjectedIdForMethod, _getOptionalDefaultAt, _getOptionalDefaultForMethod} from './decorators';\nimport {ClassConstructor, InjectableId, Injector} from './injector';\nimport {State} from './state';\nimport {isPromise} from './utils';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true **and** there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous),\n\t * **unless** the @PostConstruct method has injectable parameters, which may themselves require async resolution.\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (!asyncOnly || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) || this.postConstructHasParams())\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Returns true if the @PostConstruct method (if any) has at least one parameter.\n\t * Any parameter may require async resolution, so this class must participate in resolveSingletons.\n\t */\n\tprivate postConstructHasParams(): boolean {\n\t\tconst pcMethod =\n\t\t\t(Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, this.maker) as string | undefined) ??\n\t\t\t(Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) as string | undefined);\n\t\tif (!pcMethod)\n\t\t\treturn false;\n\t\tconst paramTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker.prototype, pcMethod) as unknown[] | undefined;\n\t\treturn Array.isArray(paramTypes) && paramTypes.length > 0;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations and/or onSuccess handler.\n\t * Any @PostConstruct method (with any injected parameters) runs first; the onSuccess handler runs after.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (obj === null || typeof obj !== 'object' || Array.isArray(obj) || !(obj as any).constructor) {\n\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t}\n\t\tconst ctor = (obj as any).constructor;\n\n\t\t// Look up the @PostConstruct method name (sync or async).\n\t\tlet pcMaybeAsync = false;\n\t\tlet pcMethodName: string | undefined = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor) as string | undefined;\n\t\tif (!pcMethodName) {\n\t\t\tpcMethodName = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor) as string | undefined;\n\t\t\tpcMaybeAsync = !!pcMethodName;\n\t\t}\n\t\tconst pcValid = !!(pcMethodName && typeof ctor.prototype[pcMethodName] === 'function');\n\t\tconst hasSuccess = typeof this.successHandler === 'function';\n\n\t\tif (!pcValid && !hasSuccess) {\n\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t}\n\n\t\t// Resolve any injectable parameters declared on the @PostConstruct method.\n\t\tconst paramStates = pcValid ? this.getMethodParameterStates(ctor, pcMethodName!) : [];\n\n\t\t// A synchronously rejected param (with no @Optional fallback) is treated as a PostConstruct error.\n\t\tconst firstRejected = paramStates.find(p => !p.pending && p.rejected);\n\t\tif (firstRejected) {\n\t\t\ttry {\n\t\t\t\tobj = this.queryErrorHandler(firstRejected.rejected, obj);\n\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t}\n\t\t}\n\n\t\tif (paramStates.some(p => p.pending)) {\n\t\t\t// One or more params require async resolution — wait for them, then invoke.\n\t\t\tconst paramsPromise = Promise.all(paramStates.map(async (p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await p.promise!;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\tconst md = _getOptionalDefaultForMethod(ctor.prototype, pcMethodName!, idx);\n\t\t\t\t\t\tif (!md) throw err;\n\t\t\t\t\t\treturn md.value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn p.fulfilled;\n\t\t\t}));\n\t\t\treturn State.MakeState<T>((async () => {\n\t\t\t\tlet args: any[];\n\t\t\t\ttry {\n\t\t\t\t\targs = await paramsPromise;\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn this.queryErrorHandler(err, obj);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst pcResult = (obj as any)[pcMethodName!](...args);\n\t\t\t\t\tif (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise(pcResult))))\n\t\t\t\t\t\tawait pcResult;\n\t\t\t\t\tif (hasSuccess) {\n\t\t\t\t\t\tconst sResult = this.successHandler!(obj, this.injector, this.id, this.maker);\n\t\t\t\t\t\tif (sResult && isPromise(sResult)) await sResult;\n\t\t\t\t\t}\n\t\t\t\t\treturn obj;\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn this.queryErrorHandler(err, obj);\n\t\t\t\t}\n\t\t\t})());\n\t\t}\n\n\t\t// All params are synchronously available (or there are no params).\n\t\tconst pcArgs = paramStates.map(p => p.fulfilled);\n\t\tconst maybeAsync = pcMaybeAsync || hasSuccess;\n\n\t\t// Build a single function that calls PostConstruct (with resolved args) then onSuccess.\n\t\tlet pcFn: (() => void | Error | Promise<void | Error>) | undefined;\n\t\tif (pcValid) {\n\t\t\tpcFn = () => {\n\t\t\t\tconst pcResult = (obj as any)[pcMethodName!](...pcArgs);\n\t\t\t\tif (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise<void>(pcResult)))) {\n\t\t\t\t\t// PostConstruct is async — chain onSuccess after it resolves.\n\t\t\t\t\treturn hasSuccess\n\t\t\t\t\t\t? (pcResult as Promise<void>).then(() => this.successHandler!(obj, this.injector, this.id, this.maker))\n\t\t\t\t\t\t: pcResult as Promise<void>;\n\t\t\t\t}\n\t\t\t\t// PostConstruct is sync — call onSuccess immediately.\n\t\t\t\tif (hasSuccess)\n\t\t\t\t\treturn this.successHandler!(obj, this.injector, this.id, this.maker) as void | Error | Promise<void | Error>;\n\t\t\t\treturn pcResult;\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\t// No PostConstruct — just call onSuccess.\n\t\t\tpcFn = () => this.successHandler!(obj, this.injector, this.id, this.maker) as void | Error | Promise<void | Error>;\n\t\t}\n\n\t\tlet result: any;\n\t\ttry {\n\t\t\tresult = pcFn();\n\t\t}\n\t\tcatch (err) {\n\t\t\ttry {\n\t\t\t\tobj = this.queryErrorHandler(err, obj);\n\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t}\n\t\t}\n\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t}\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * Collects the resolved States for all injectable parameters of a @PostConstruct method.\n\t * Uses the same resolution rules as constructor parameters: the reflected type (or an explicit @Inject token) is used to look up the binding, and an error is thrown if the type cannot be determined.\n\t * Use @Optional() on a parameter to supply a fallback when no binding is found.\n\t * Returns an empty array if the method has no parameters.\n\t */\n\tprotected getMethodParameterStates(ctor: Function, methodName: string): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, ctor.prototype, methodName) as unknown[] | undefined;\n\t\tif (!Array.isArray(argTypes) || argTypes.length === 0)\n\t\t\treturn [];\n\t\treturn argTypes.map((argType, index) => {\n\t\t\tconst overrideToken = _getInjectedIdForMethod(ctor.prototype, methodName, index);\n\t\t\tconst actualToken = overrideToken !== undefined ? overrideToken : argType;\n\t\t\tif (actualToken == null) {\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${(ctor as any).name}.${methodName}`);\n\t\t\t}\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken as InjectableId<unknown>);\n\t\t\tif (!param.pending && param.rejected) {\n\t\t\t\tconst optionalDefault = _getOptionalDefaultForMethod(ctor.prototype, methodName, index);\n\t\t\t\tif (optionalDefault)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, optionalDefault.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies returning undefined instead.\n\t\t\t// Additionally, it cannot return generic types (no runtime type info).\n\t\t\t// If an Inject annotation precedes the parameter, then that is what should get injected.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\t// If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\tif (actualToken === undefined) {\n\t\t\t\t// No Inject annotation, and the type is not known.\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);\n\t\t\t}\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst firstRejectedParam = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (firstRejectedParam)\n\t\t\treturn firstRejectedParam as State<T>;\n\t\tif (params.some(p => p.pending)) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\t// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.\n\t\t\t// This might create some unnecessary (but immediately resolved) Promise objects,\n\t\t\t// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(params.map(async (p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await p.promise!;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t// This was a promised param that failed to resolve.\n\t\t\t\t\t\t// If there is an Optional decorator, use that, otherwise, failure is failure.\n\t\t\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, idx);\n\t\t\t\t\t\tif (!md)\n\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\treturn md.value as unknown;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn p.fulfilled;\n\t\t\t})), (values) => {\n\t\t\t\tif (values) {\n\t\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\t\treturn Reflect.construct(this.maker, values);\n\t\t\t\t}\n\t\t\t\treturn undefined as unknown as T;\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>((async () => {\n\t\t\t\tconst obj = await objPromise;\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn await state.promise!; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\tthrow state.rejected; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled!; // value (aka obj).\n\t\t\t\t}\n\t\t\t})());\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -17,7 +17,7 @@ class ReasonWrapper {
17
17
  }
18
18
  }
19
19
  /**
20
- * Binder and Injector (aka Container) to handle (a)synchronous dependency management.
20
+ * Injector (aka Container) to handle (a)synchronous dependency management.
21
21
  */
22
22
  export class Container {
23
23
  /**
@@ -31,7 +31,7 @@ export class Container {
31
31
  * @inheritDoc
32
32
  */
33
33
  isIdKnown(id, ascending) {
34
- if (!!this.providers.get(id))
34
+ if (this.providers.has(id))
35
35
  return true;
36
36
  if (ascending && this.parent)
37
37
  return this.parent.isIdKnown(id, true);
@@ -67,27 +67,70 @@ export class Container {
67
67
  }
68
68
  return Promise.resolve(state.fulfilled);
69
69
  }
70
- // noinspection JSUnusedGlobalSymbols
71
70
  /**
72
- * This method is not part of the Binding interface, because it is highly unusual.
73
- * But that doesn't mean we can't imagine scenarios where you might require it.
71
+ * Removes a binding from this Container (and optionally its ancestor chain).
72
+ * Most useful in unit tests to replace or clear bindings between test cases.
73
+ * **Caution:** Removing a binding after initialization may have unexpected consequences if other parts of the application still hold or expect to obtain an instance of the removed id.
74
74
  *
75
- * @param id The id to be removed.
76
- * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).
77
- * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.
75
+ * @param id The id of the binding to remove.
76
+ * @param ascending If true, the binding is also removed from every Container in the parent chain.
77
+ * @param releaseIfSingleton If true, Provider.releaseIfSingleton is called before removal.
78
78
  */
79
79
  removeBinding(id, ascending, releaseIfSingleton) {
80
- var _a;
81
80
  if (releaseIfSingleton) {
82
81
  const p = this.providers.get(id);
83
82
  if (p)
84
83
  p.releaseIfSingleton();
85
84
  }
86
85
  this.providers.delete(id);
87
- if (ascending && this.parent) {
88
- (_a = this.parent) === null || _a === void 0 ? void 0 : _a.removeBinding(id, true, releaseIfSingleton);
86
+ if (ascending && this.parent instanceof Container) {
87
+ this.parent.removeBinding(id, true, releaseIfSingleton);
89
88
  }
90
89
  }
90
+ /**
91
+ * Alias for {@link isIdKnown}. Familiar to users migrating from TypeDI.
92
+ */
93
+ has(id, ascending) {
94
+ return this.isIdKnown(id, ascending);
95
+ }
96
+ /**
97
+ * Alias for {@link removeBinding}. Familiar to users migrating from InversifyJS.
98
+ */
99
+ unbind(id, ascending, releaseIfSingleton) {
100
+ this.removeBinding(id, ascending, releaseIfSingleton);
101
+ }
102
+ /**
103
+ * Creates a new child Container that inherits unbound ids from this Container.
104
+ * Familiar to users migrating from TSyringe.
105
+ */
106
+ createChildContainer() {
107
+ return new Container(this);
108
+ }
109
+ /**
110
+ * Descriptor-based binding dispatching to the appropriate bindXXX method.
111
+ * Familiar to users migrating from TSyringe.
112
+ * Returns a {@link BindAs} chain for class and factory bindings; returns undefined for value bindings (which are always singletons).
113
+ */
114
+ register(id, descriptor) {
115
+ if ('useClass' in descriptor)
116
+ return this.bindClass(id, descriptor.useClass);
117
+ if ('useValue' in descriptor) {
118
+ this.bindConstant(id, descriptor.useValue);
119
+ return undefined;
120
+ }
121
+ if ('useFactory' in descriptor)
122
+ return this.bindFactory(id, descriptor.useFactory);
123
+ // useAsyncFactory
124
+ return this.bindAsyncFactory(id, descriptor.useAsyncFactory);
125
+ }
126
+ /**
127
+ * Binds a class as a singleton in one step.
128
+ * Shorthand for {@link bindClass}(...).{@link BindAs.asSingleton asSingleton}().
129
+ * Familiar to users migrating from TSyringe.
130
+ */
131
+ registerSingleton(id, constructor) {
132
+ this.bindClass(id, constructor).asSingleton();
133
+ }
91
134
  /**
92
135
  * @inheritDoc
93
136
  */
@@ -126,7 +169,6 @@ export class Container {
126
169
  * @inheritDoc
127
170
  */
128
171
  resolveSingletons(asyncOnly, parentRecursion) {
129
- var _a;
130
172
  const makePromiseToResolve = () => {
131
173
  return new Promise((resolve, reject) => {
132
174
  const pending = new Map();
@@ -160,9 +202,8 @@ export class Container {
160
202
  });
161
203
  });
162
204
  };
163
- if (parentRecursion && typeof ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.resolveSingletons) === 'function') {
164
- const pb = this.parent;
165
- return pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {
205
+ if (parentRecursion && this.parent instanceof Container) {
206
+ return this.parent.resolveSingletons(asyncOnly, parentRecursion).then(() => {
166
207
  return makePromiseToResolve().then(() => this);
167
208
  });
168
209
  }
@@ -192,14 +233,13 @@ export class Container {
192
233
  }
193
234
  return provider.provideAsState();
194
235
  }
195
- // noinspection JSUnusedGlobalSymbols
196
236
  /**
197
237
  * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.
198
- * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.
199
- * This method is not part of the Binding interface, because you normally only create (and release) Containers.
238
+ * It will walk through all registered Providers (of this Container only), and invoke their Provider.releaseIfSingleton method.
239
+ * This method is not part of the Injector interface, because you normally only create (and release) from Containers.
200
240
  * NOTE:
201
241
  * This *only* releases active/pending Singleton's that have already been created by this Container.
202
- * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.
242
+ * The most likely use of this method would be when you have created a new child Container for a limited-duration transaction, and you want to easily clean up temporary resources.
203
243
  * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).
204
244
  * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.
205
245
  */
@@ -210,7 +250,7 @@ export class Container {
210
250
  }
211
251
  /**
212
252
  * Releases a Singleton instance if it exists.
213
- * However, it does **not** remove the binding, so if you call @get or @resolve (directly or indirectly) on the id, a new Singleton will be created.
253
+ * However, it does **not** remove the binding, so if you call get or resolve (directly or indirectly) on the id, a new Singleton will be created.
214
254
  * If not a singleton, this method returns undefined.
215
255
  * If the singleton has been resolved, it is returned, otherwise null is returned.
216
256
  * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.
@@ -223,7 +263,7 @@ export class Container {
223
263
  return undefined;
224
264
  }
225
265
  /**
226
- * Make a copy of this @see Container.
266
+ * Make a copy of this Container.
227
267
  * This is an experimental feature!
228
268
  * I have not thought through all the dark corners, so use at your own peril!
229
269
  * Here are some notes:
@@ -235,7 +275,7 @@ export class Container {
235
275
  * If released by the clone, they will be considered released by "this" container.
236
276
  * If a singleton is currently being asynchronously constructed any callbacks will reference "this" Container, however both Containers should have no problem awaiting resolution.
237
277
  * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* "singletons".
238
- * The way to avoid this last effect is to @see resolveSingletons
278
+ * The way to avoid this last effect is to call resolveSingletons first
239
279
  */
240
280
  clone(clazz) {
241
281
  if (!clazz)
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider';\nimport {BindableProvider} from './bindable-provider';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder';\nimport {ClassBasedProvider} from './class-provider';\nimport {ConstantProvider} from './constant-provider';\nimport {INJECTABLE_METADATA_KEY} from './constants';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {State} from './state';\nimport {FactoryBasedProvider} from './sync-factory-provider';\nimport {isPromise} from './utils';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly ?? false);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Releases a Singleton instance if it exists.\n\t * However, it does **not** remove the binding, so if you call @get or @resolve (directly or indirectly) on the id, a new Singleton will be created.\n\t * If not a singleton, this method returns undefined.\n\t * If the singleton has been resolved, it is returned, otherwise null is returned.\n\t * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.\n\t * Note that if a singleton is returned, its Release method will already have been invoked.\n\t */\n\tpublic releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (provider)\n\t\t\treturn provider.releaseIfSingleton();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider';\nimport {BindableProvider} from './bindable-provider';\nimport {AsyncFactory, BindAs, RegisterDescriptor, SyncFactory} from './binding';\nimport {ClassBasedProvider} from './class-provider';\nimport {ConstantProvider} from './constant-provider';\nimport {INJECTABLE_METADATA_KEY} from './constants';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {State} from './state';\nimport {FactoryBasedProvider} from './sync-factory-provider';\nimport {isPromise} from './utils';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Injector {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (this.providers.has(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t/**\n\t * Removes a binding from this Container (and optionally its ancestor chain).\n\t * Most useful in unit tests to replace or clear bindings between test cases.\n\t * **Caution:** Removing a binding after initialization may have unexpected consequences if other parts of the application still hold or expect to obtain an instance of the removed id.\n\t *\n\t * @param id The id of the binding to remove.\n\t * @param ascending If true, the binding is also removed from every Container in the parent chain.\n\t * @param releaseIfSingleton If true, Provider.releaseIfSingleton is called before removal.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent instanceof Container) {\n\t\t\tthis.parent.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\n\t/**\n\t * Alias for {@link isIdKnown}. Familiar to users migrating from TypeDI.\n\t */\n\tpublic has<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\treturn this.isIdKnown(id, ascending);\n\t}\n\n\t/**\n\t * Alias for {@link removeBinding}. Familiar to users migrating from InversifyJS.\n\t */\n\tpublic unbind<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tthis.removeBinding(id, ascending, releaseIfSingleton);\n\t}\n\n\t/**\n\t * Creates a new child Container that inherits unbound ids from this Container.\n\t * Familiar to users migrating from TSyringe.\n\t */\n\tpublic createChildContainer(): Container {\n\t\treturn new Container(this);\n\t}\n\n\t/**\n\t * Descriptor-based binding dispatching to the appropriate bindXXX method.\n\t * Familiar to users migrating from TSyringe.\n\t * Returns a {@link BindAs} chain for class and factory bindings; returns undefined for value bindings (which are always singletons).\n\t */\n\tpublic register<T>(id: InjectableId<T>, descriptor: RegisterDescriptor<T>): BindAs<T, any> | undefined {\n\t\tif ('useClass' in descriptor)\n\t\t\treturn this.bindClass(id as any, descriptor.useClass);\n\t\tif ('useValue' in descriptor) {\n\t\t\tthis.bindConstant(id, descriptor.useValue);\n\t\t\treturn undefined;\n\t\t}\n\t\tif ('useFactory' in descriptor)\n\t\t\treturn this.bindFactory(id, descriptor.useFactory);\n\t\t// useAsyncFactory\n\t\treturn this.bindAsyncFactory(id, (descriptor as {useAsyncFactory: AsyncFactory<T>}).useAsyncFactory);\n\t}\n\n\t/**\n\t * Binds a class as a singleton in one step.\n\t * Shorthand for {@link bindClass}(...).{@link BindAs.asSingleton asSingleton}().\n\t * Familiar to users migrating from TSyringe.\n\t */\n\tpublic registerSingleton<T>(id: InjectableId<T>, constructor: ClassConstructor<T>): void {\n\t\tthis.bindClass(id as any, constructor).asSingleton();\n\t}\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly ?? false);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && this.parent instanceof Container) {\n\t\t\treturn this.parent.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their Provider.releaseIfSingleton method.\n\t * This method is not part of the Injector interface, because you normally only create (and release) from Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited-duration transaction, and you want to easily clean up temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Releases a Singleton instance if it exists.\n\t * However, it does **not** remove the binding, so if you call get or resolve (directly or indirectly) on the id, a new Singleton will be created.\n\t * If not a singleton, this method returns undefined.\n\t * If the singleton has been resolved, it is returned, otherwise null is returned.\n\t * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.\n\t * Note that if a singleton is returned, its Release method will already have been invoked.\n\t */\n\tpublic releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (provider)\n\t\t\treturn provider.releaseIfSingleton();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a copy of this Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to call resolveSingletons first\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}