@wessberg/di
Advanced tools
Comparing version 1.0.30 to 1.1.0
@@ -0,1 +1,9 @@ | ||
## 1.1.0 (2018-07-03) | ||
* 1.1.0 ([2fb72d6](https://github.com/wessberg/di/commit/2fb72d6)) | ||
* Bumped version ([373f14b](https://github.com/wessberg/di/commit/373f14b)) | ||
* Fixed an issue with automatically detecting and proxying circular dependencies ([5b26d8d](https://github.com/wessberg/di/commit/5b26d8d)) | ||
## <small>1.0.30 (2018-06-21)</small> | ||
@@ -2,0 +10,0 @@ |
import { IContainerIdentifierable } from "../container-identifierable/i-container-identifierable"; | ||
export interface IConstructInstanceOptions extends IContainerIdentifierable { | ||
parent?: string; | ||
import { IParent } from "./i-parent"; | ||
export interface IConstructInstanceOptions<T> extends IContainerIdentifierable { | ||
parentChain?: IParent<{}>[]; | ||
} |
@@ -100,12 +100,10 @@ import { IGetOptions } from "../get-options/i-get-options"; | ||
/** | ||
* Gets a proxied instance | ||
* @param {T} instance | ||
* @returns {T} | ||
* Gets a lazy reference to another service | ||
* @param lazyPointer | ||
*/ | ||
private getLazyInstance; | ||
private getLazyIdentifier; | ||
/** | ||
* Constructs a new instance of the given identifier and returns it. | ||
* It checks the constructor arguments and injects any services it might depend on recursively. | ||
* @param {string} identifier | ||
* @param {string?} parent | ||
* @param {IConstructInstanceOptions<T>} options | ||
* @returns {T} | ||
@@ -112,0 +110,0 @@ */ |
@@ -121,6 +121,6 @@ import { CONSTRUCTOR_ARGUMENTS_IDENTIFIER } from "../constructor-arguments/constructor-arguments-identifier"; | ||
*/ | ||
getRegistrationRecord({ identifier, parent }) { | ||
getRegistrationRecord({ identifier, parentChain }) { | ||
const record = this.serviceRegistry.get(identifier); | ||
if (record == null) | ||
throw new ReferenceError(`${this.constructor.name} could not find a service for identifier: "${identifier}". ${parent == null ? "" : `It is required by the service: '${parent}'.`} Remember to register it as a service!`); | ||
throw new ReferenceError(`${this.constructor.name} could not find a service for identifier: "${identifier}". ${parentChain == null || parentChain.length < 1 ? "" : `It is required by the service: '${parentChain.map(parent => parent.identifier).join(" -> ")}'.`} Remember to register it as a service!`); | ||
return record; | ||
@@ -139,8 +139,7 @@ } | ||
/** | ||
* Gets a proxied instance | ||
* @param {T} instance | ||
* @returns {T} | ||
* Gets a lazy reference to another service | ||
* @param lazyPointer | ||
*/ | ||
getLazyInstance(instance) { | ||
return new Proxy({}, { get: (_, key) => instance[key] }); | ||
getLazyIdentifier(lazyPointer) { | ||
return new Proxy({}, { get: (_, key) => lazyPointer()[key] }); | ||
} | ||
@@ -150,8 +149,7 @@ /** | ||
* It checks the constructor arguments and injects any services it might depend on recursively. | ||
* @param {string} identifier | ||
* @param {string?} parent | ||
* @param {IConstructInstanceOptions<T>} options | ||
* @returns {T} | ||
*/ | ||
constructInstance({ identifier, parent }) { | ||
const registrationRecord = this.getRegistrationRecord({ identifier, parent }); | ||
constructInstance({ identifier, parentChain = [] }) { | ||
const registrationRecord = this.getRegistrationRecord({ identifier, parentChain }); | ||
// If an instance already exists (and it is a singleton), return that one | ||
@@ -163,3 +161,6 @@ if (this.hasInstance(identifier) && registrationRecord.kind === RegistrationKind.SINGLETON) { | ||
let instance; | ||
let circular = false; | ||
const me = { | ||
identifier, | ||
ref: this.getLazyIdentifier(() => instance) | ||
}; | ||
// If a user-provided new-expression has been provided, invoke that to get an instance. | ||
@@ -175,5 +176,10 @@ if (registrationRecord.newExpression != null) { | ||
// Instantiate all of the argument services (or re-use them if they were registered as singletons) | ||
const instanceArgs = mappedArgs.map((dep) => dep === undefined ? undefined : this.constructInstance({ identifier: dep, parent: identifier })); | ||
// It is circular if any of the arguments are identical to that of the identifier | ||
circular = mappedArgs.some(arg => arg === identifier); | ||
const instanceArgs = mappedArgs.map((dep) => { | ||
if (dep === undefined) | ||
return undefined; | ||
const matchedParent = parentChain.find(parent => parent.identifier === dep); | ||
if (matchedParent != null) | ||
return matchedParent.ref; | ||
return this.constructInstance({ identifier: dep, parentChain: [...parentChain, me] }); | ||
}); | ||
try { | ||
@@ -192,6 +198,2 @@ // Try to construct an instance with 'new' and if it fails, call the implementation directly. | ||
} | ||
// Make the instance lazy if 'circular' is given in the RegistrationOptions | ||
if (circular) { | ||
instance = this.getLazyInstance(instance); | ||
} | ||
return registrationRecord.kind === RegistrationKind.SINGLETON ? this.setInstance(identifier, instance) : instance; | ||
@@ -198,0 +200,0 @@ } |
import { IContainerIdentifierable } from "../container-identifierable/i-container-identifierable"; | ||
export interface IConstructInstanceOptions extends IContainerIdentifierable { | ||
parent?: string; | ||
import { IParent } from "./i-parent"; | ||
export interface IConstructInstanceOptions<T> extends IContainerIdentifierable { | ||
parentChain?: IParent<{}>[]; | ||
} |
@@ -100,12 +100,10 @@ import { IGetOptions } from "../get-options/i-get-options"; | ||
/** | ||
* Gets a proxied instance | ||
* @param {T} instance | ||
* @returns {T} | ||
* Gets a lazy reference to another service | ||
* @param lazyPointer | ||
*/ | ||
private getLazyInstance; | ||
private getLazyIdentifier; | ||
/** | ||
* Constructs a new instance of the given identifier and returns it. | ||
* It checks the constructor arguments and injects any services it might depend on recursively. | ||
* @param {string} identifier | ||
* @param {string?} parent | ||
* @param {IConstructInstanceOptions<T>} options | ||
* @returns {T} | ||
@@ -112,0 +110,0 @@ */ |
@@ -132,6 +132,6 @@ (function (factory) { | ||
*/ | ||
getRegistrationRecord({ identifier, parent }) { | ||
getRegistrationRecord({ identifier, parentChain }) { | ||
const record = this.serviceRegistry.get(identifier); | ||
if (record == null) | ||
throw new ReferenceError(`${this.constructor.name} could not find a service for identifier: "${identifier}". ${parent == null ? "" : `It is required by the service: '${parent}'.`} Remember to register it as a service!`); | ||
throw new ReferenceError(`${this.constructor.name} could not find a service for identifier: "${identifier}". ${parentChain == null || parentChain.length < 1 ? "" : `It is required by the service: '${parentChain.map(parent => parent.identifier).join(" -> ")}'.`} Remember to register it as a service!`); | ||
return record; | ||
@@ -150,8 +150,7 @@ } | ||
/** | ||
* Gets a proxied instance | ||
* @param {T} instance | ||
* @returns {T} | ||
* Gets a lazy reference to another service | ||
* @param lazyPointer | ||
*/ | ||
getLazyInstance(instance) { | ||
return new Proxy({}, { get: (_, key) => instance[key] }); | ||
getLazyIdentifier(lazyPointer) { | ||
return new Proxy({}, { get: (_, key) => lazyPointer()[key] }); | ||
} | ||
@@ -161,8 +160,7 @@ /** | ||
* It checks the constructor arguments and injects any services it might depend on recursively. | ||
* @param {string} identifier | ||
* @param {string?} parent | ||
* @param {IConstructInstanceOptions<T>} options | ||
* @returns {T} | ||
*/ | ||
constructInstance({ identifier, parent }) { | ||
const registrationRecord = this.getRegistrationRecord({ identifier, parent }); | ||
constructInstance({ identifier, parentChain = [] }) { | ||
const registrationRecord = this.getRegistrationRecord({ identifier, parentChain }); | ||
// If an instance already exists (and it is a singleton), return that one | ||
@@ -174,3 +172,6 @@ if (this.hasInstance(identifier) && registrationRecord.kind === registration_kind_1.RegistrationKind.SINGLETON) { | ||
let instance; | ||
let circular = false; | ||
const me = { | ||
identifier, | ||
ref: this.getLazyIdentifier(() => instance) | ||
}; | ||
// If a user-provided new-expression has been provided, invoke that to get an instance. | ||
@@ -186,5 +187,10 @@ if (registrationRecord.newExpression != null) { | ||
// Instantiate all of the argument services (or re-use them if they were registered as singletons) | ||
const instanceArgs = mappedArgs.map((dep) => dep === undefined ? undefined : this.constructInstance({ identifier: dep, parent: identifier })); | ||
// It is circular if any of the arguments are identical to that of the identifier | ||
circular = mappedArgs.some(arg => arg === identifier); | ||
const instanceArgs = mappedArgs.map((dep) => { | ||
if (dep === undefined) | ||
return undefined; | ||
const matchedParent = parentChain.find(parent => parent.identifier === dep); | ||
if (matchedParent != null) | ||
return matchedParent.ref; | ||
return this.constructInstance({ identifier: dep, parentChain: [...parentChain, me] }); | ||
}); | ||
try { | ||
@@ -203,6 +209,2 @@ // Try to construct an instance with 'new' and if it fails, call the implementation directly. | ||
} | ||
// Make the instance lazy if 'circular' is given in the RegistrationOptions | ||
if (circular) { | ||
instance = this.getLazyInstance(instance); | ||
} | ||
return registrationRecord.kind === registration_kind_1.RegistrationKind.SINGLETON ? this.setInstance(identifier, instance) : instance; | ||
@@ -209,0 +211,0 @@ } |
{ | ||
"name": "@wessberg/di", | ||
"version": "1.0.30", | ||
"version": "1.1.0", | ||
"description": "A Dependency-Injection container that holds services and can produce instances of them as required. It mimics reflection by parsing the app at compile-time and supporting the generic-reflection syntax.", | ||
@@ -5,0 +5,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72491
93
937