feat(injector): change injector to recover from errors
So it can instantiate an object after a failed attempt.
This commit is contained in:
parent
b9d03e6635
commit
9b411372df
|
@ -94,6 +94,14 @@ export class Injector {
|
||||||
if (this._bindings.length <= key.id) return null;
|
if (this._bindings.length <= key.id) return null;
|
||||||
return ListWrapper.get(this._bindings, key.id);
|
return ListWrapper.get(this._bindings, key.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_markAsConstructing(key:Key) {
|
||||||
|
this._setInstance(key, _constructing);
|
||||||
|
}
|
||||||
|
|
||||||
|
_clear(key:Key) {
|
||||||
|
this._setInstance(key, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,7 +133,7 @@ class _SyncInjectorStrategy {
|
||||||
if (binding.providedAsFuture) throw new AsyncBindingError(key);
|
if (binding.providedAsFuture) throw new AsyncBindingError(key);
|
||||||
|
|
||||||
//add a marker so we can detect cyclic dependencies
|
//add a marker so we can detect cyclic dependencies
|
||||||
this.injector._setInstance(key, _constructing);
|
this.injector._markAsConstructing(key);
|
||||||
|
|
||||||
var deps = this._resolveDependencies(key, binding);
|
var deps = this._resolveDependencies(key, binding);
|
||||||
return this._createInstance(key, binding, deps);
|
return this._createInstance(key, binding, deps);
|
||||||
|
@ -136,7 +144,7 @@ class _SyncInjectorStrategy {
|
||||||
var getDependency = d => this.injector._getByKey(d.key, d.asFuture, d.lazy);
|
var getDependency = d => this.injector._getByKey(d.key, d.asFuture, d.lazy);
|
||||||
return ListWrapper.map(binding.dependencies, getDependency);
|
return ListWrapper.map(binding.dependencies, getDependency);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.injector._setInstance(key, null);
|
this.injector._clear(key);
|
||||||
if (e instanceof ProviderError) e.addKey(key);
|
if (e instanceof ProviderError) e.addKey(key);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +156,7 @@ class _SyncInjectorStrategy {
|
||||||
this.injector._setInstance(key, instance);
|
this.injector._setInstance(key, instance);
|
||||||
return instance;
|
return instance;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
this.injector._clear(key);
|
||||||
throw new InstantiationError(e, key);
|
throw new InstantiationError(e, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +191,7 @@ class _AsyncInjectorStrategy {
|
||||||
if (isBlank(binding)) return null;
|
if (isBlank(binding)) return null;
|
||||||
|
|
||||||
//add a marker so we can detect cyclic dependencies
|
//add a marker so we can detect cyclic dependencies
|
||||||
this.injector._setInstance(key, _constructing);
|
this.injector._markAsConstructing(key);
|
||||||
|
|
||||||
var deps = this._resolveDependencies(key, binding);
|
var deps = this._resolveDependencies(key, binding);
|
||||||
var depsFuture = FutureWrapper.wait(deps);
|
var depsFuture = FutureWrapper.wait(deps);
|
||||||
|
@ -200,7 +209,7 @@ class _AsyncInjectorStrategy {
|
||||||
var getDependency = d => this.injector._getByKey(d.key, true, d.lazy);
|
var getDependency = d => this.injector._getByKey(d.key, true, d.lazy);
|
||||||
return ListWrapper.map(binding.dependencies, getDependency);
|
return ListWrapper.map(binding.dependencies, getDependency);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.injector._setInstance(key, null);
|
this.injector._clear(key);
|
||||||
if (e instanceof ProviderError) e.addKey(key);
|
if (e instanceof ProviderError) e.addKey(key);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +226,7 @@ class _AsyncInjectorStrategy {
|
||||||
if (!_isWaiting(instance)) return instance;
|
if (!_isWaiting(instance)) return instance;
|
||||||
return binding.factory(deps);
|
return binding.factory(deps);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
this.injector._clear(key);
|
||||||
throw new InstantiationError(e, key);
|
throw new InstantiationError(e, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,21 @@ export function main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should instantiate an object after a failed attempt', function () {
|
||||||
|
var isBroken = true;
|
||||||
|
|
||||||
|
var injector = new Injector([
|
||||||
|
Car,
|
||||||
|
bind(Engine).toFactory([], () => isBroken ? new BrokenEngine() : new Engine())
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(() => injector.get(Car)).toThrow();
|
||||||
|
|
||||||
|
isBroken = false;
|
||||||
|
|
||||||
|
expect(injector.get(Car)).toBeAnInstanceOf(Car);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("child", function () {
|
describe("child", function () {
|
||||||
it('should load instances from parent injector', function () {
|
it('should load instances from parent injector', function () {
|
||||||
|
|
Loading…
Reference in New Issue