refactor(Injector): add an interface for strategies

This commit is contained in:
Victor Berchet 2015-05-29 15:04:42 +02:00
parent db7a1f19ba
commit e93b5a1d5b
1 changed files with 24 additions and 23 deletions

View File

@ -260,17 +260,20 @@ export class Injector {
_clear(key: Key): void { this._setInstance(key, null); } _clear(key: Key): void { this._setInstance(key, null); }
} }
interface _InjectorStrategy {
readFromCache(key: Key);
instantiate(key: Key);
}
class _SyncInjectorStrategy { class _SyncInjectorStrategy implements _InjectorStrategy {
injector: Injector; constructor(private _injector: Injector) { }
constructor(injector: Injector) { this.injector = injector; }
readFromCache(key: Key) { readFromCache(key: Key) {
if (key.token === Injector) { if (key.token === Injector) {
return this.injector; return this._injector;
} }
var instance = this.injector._getInstance(key); var instance = this._injector._getInstance(key);
if (instance === _constructing) { if (instance === _constructing) {
throw new CyclicDependencyError(key); throw new CyclicDependencyError(key);
@ -282,41 +285,39 @@ class _SyncInjectorStrategy {
} }
instantiate(key: Key) { instantiate(key: Key) {
var binding = this.injector._getBinding(key); var binding = this._injector._getBinding(key);
if (isBlank(binding)) return _notFound; if (isBlank(binding)) return _notFound;
if (binding.providedAsPromise) throw new AsyncBindingError(key); if (binding.providedAsPromise) throw new AsyncBindingError(key);
// add a marker so we can detect cyclic dependencies // add a marker so we can detect cyclic dependencies
this.injector._markAsConstructing(key); this._injector._markAsConstructing(key);
var deps = this.injector._resolveDependencies(key, binding, false); var deps = this._injector._resolveDependencies(key, binding, false);
return this._createInstance(key, binding, deps); return this._createInstance(key, binding, deps);
} }
_createInstance(key: Key, binding: ResolvedBinding, deps: List<any>) { _createInstance(key: Key, binding: ResolvedBinding, deps: List<any>) {
try { try {
var instance = FunctionWrapper.apply(binding.factory, deps); var instance = FunctionWrapper.apply(binding.factory, deps);
this.injector._setInstance(key, instance); this._injector._setInstance(key, instance);
return instance; return instance;
} catch (e) { } catch (e) {
this.injector._clear(key); this._injector._clear(key);
throw new InstantiationError(e, key); throw new InstantiationError(e, key);
} }
} }
} }
class _AsyncInjectorStrategy implements _InjectorStrategy {
class _AsyncInjectorStrategy { constructor(private _injector: Injector) { }
injector: Injector;
constructor(injector: Injector) { this.injector = injector; }
readFromCache(key: Key) { readFromCache(key: Key) {
if (key.token === Injector) { if (key.token === Injector) {
return PromiseWrapper.resolve(this.injector); return PromiseWrapper.resolve(this._injector);
} }
var instance = this.injector._getInstance(key); var instance = this._injector._getInstance(key);
if (instance === _constructing) { if (instance === _constructing) {
throw new CyclicDependencyError(key); throw new CyclicDependencyError(key);
@ -330,20 +331,20 @@ class _AsyncInjectorStrategy {
} }
instantiate(key: Key) /* Promise?? */ { instantiate(key: Key) /* Promise?? */ {
var binding = this.injector._getBinding(key); var binding = this._injector._getBinding(key);
if (isBlank(binding)) return _notFound; if (isBlank(binding)) return _notFound;
// add a marker so we can detect cyclic dependencies // add a marker so we can detect cyclic dependencies
this.injector._markAsConstructing(key); this._injector._markAsConstructing(key);
var deps = this.injector._resolveDependencies(key, binding, true); var deps = this._injector._resolveDependencies(key, binding, true);
var depsPromise = PromiseWrapper.all(deps); var depsPromise = PromiseWrapper.all(deps);
var promise = PromiseWrapper.then(depsPromise, null, (e, s) => this._errorHandler(key, e, s)) var promise = PromiseWrapper.then(depsPromise, null, (e, s) => this._errorHandler(key, e, s))
.then(deps => this._findOrCreate(key, binding, deps)) .then(deps => this._findOrCreate(key, binding, deps))
.then(instance => this._cacheInstance(key, instance)); .then(instance => this._cacheInstance(key, instance));
this.injector._setInstance(key, new _Waiting(promise)); this._injector._setInstance(key, new _Waiting(promise));
return promise; return promise;
} }
@ -354,17 +355,17 @@ class _AsyncInjectorStrategy {
_findOrCreate(key: Key, binding: ResolvedBinding, deps: List<any>) { _findOrCreate(key: Key, binding: ResolvedBinding, deps: List<any>) {
try { try {
var instance = this.injector._getInstance(key); var instance = this._injector._getInstance(key);
if (!_isWaiting(instance)) return instance; if (!_isWaiting(instance)) return instance;
return FunctionWrapper.apply(binding.factory, deps); return FunctionWrapper.apply(binding.factory, deps);
} catch (e) { } catch (e) {
this.injector._clear(key); this._injector._clear(key);
throw new InstantiationError(e, key); throw new InstantiationError(e, key);
} }
} }
_cacheInstance(key, instance) { _cacheInstance(key, instance) {
this.injector._setInstance(key, instance); this._injector._setInstance(key, instance);
return instance return instance
} }
} }