refactor(injector): change toFactory to use reflector to construct dependencies
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import {FIELD, Type, bool} from 'facade/lang';
|
||||
import {FIELD, Type, bool, isBlank} from 'facade/lang';
|
||||
import {List, MapWrapper, ListWrapper} from 'facade/collection';
|
||||
import {reflector} from './reflector';
|
||||
import {Key} from './key';
|
||||
@ -13,6 +13,7 @@ export class Dependency {
|
||||
this.lazy = lazy;
|
||||
}
|
||||
}
|
||||
|
||||
export class Binding {
|
||||
constructor(key:Key, factory:Function, dependencies:List, providedAsFuture:bool) {
|
||||
this.key = key;
|
||||
@ -49,25 +50,27 @@ export class BindingBuilder {
|
||||
);
|
||||
}
|
||||
|
||||
toFactory(dependencies:List, factoryFunction:Function):Binding {
|
||||
toFactory(factoryFunction:Function, {dependencies=null}={}):Binding {
|
||||
return new Binding(
|
||||
Key.get(this.token),
|
||||
reflector.convertToFactory(factoryFunction),
|
||||
this._constructDependencies(dependencies),
|
||||
this._constructDependencies(factoryFunction, dependencies),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
toAsyncFactory(dependencies:List, factoryFunction:Function):Binding {
|
||||
toAsyncFactory(factoryFunction:Function, {dependencies=null}={}):Binding {
|
||||
return new Binding(
|
||||
Key.get(this.token),
|
||||
reflector.convertToFactory(factoryFunction),
|
||||
this._constructDependencies(dependencies),
|
||||
this._constructDependencies(factoryFunction, dependencies),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
_constructDependencies(deps:List) {
|
||||
return ListWrapper.map(deps, (t) => new Dependency(Key.get(t), false, false));
|
||||
_constructDependencies(factoryFunction:Function, dependencies:List) {
|
||||
return isBlank(dependencies) ?
|
||||
reflector.dependencies(factoryFunction) :
|
||||
ListWrapper.map(dependencies, (t) => new Dependency(Key.get(t), false, false));
|
||||
}
|
||||
}
|
@ -77,8 +77,8 @@ export class InvalidBindingError extends Error {
|
||||
}
|
||||
|
||||
export class NoAnnotationError extends Error {
|
||||
constructor(type) {
|
||||
this.message = `Cannot resolve all parameters for ${stringify(type)}`;
|
||||
constructor(typeOrFunc) {
|
||||
this.message = `Cannot resolve all parameters for ${stringify(typeOrFunc)}`;
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
@ -23,12 +23,13 @@ class Reflector {
|
||||
return (args) => create(name, args).reflectee;
|
||||
}
|
||||
|
||||
List<Dependency> dependencies(Type type) {
|
||||
ClassMirror classMirror = reflectType(type);
|
||||
MethodMirror ctor = classMirror.declarations[classMirror.simpleName];
|
||||
List<Dependency> dependencies(typeOrFunc) {
|
||||
final parameters = typeOrFunc is Type ?
|
||||
_constructorParameters(typeOrFunc) :
|
||||
_functionParameters(typeOrFunc);
|
||||
|
||||
return new List.generate(ctor.parameters.length, (int pos) {
|
||||
ParameterMirror p = ctor.parameters[pos];
|
||||
return new List.generate(parameters.length, (int pos) {
|
||||
ParameterMirror p = parameters[pos];
|
||||
|
||||
final metadata = p.metadata.map((m) => m.reflectee);
|
||||
|
||||
@ -49,10 +50,20 @@ class Reflector {
|
||||
return new Dependency(Key.get(p.type.reflectedType), false, false);
|
||||
|
||||
} else {
|
||||
throw new NoAnnotationError(type);
|
||||
throw new NoAnnotationError(typeOrFunc);
|
||||
}
|
||||
}, growable:false);
|
||||
}
|
||||
|
||||
List<ParameterMirror> _functionParameters(Function func) {
|
||||
return reflect(func).function.parameters;
|
||||
}
|
||||
|
||||
List<ParameterMirror> _constructorParameters(Type type) {
|
||||
ClassMirror classMirror = reflectType(type);
|
||||
MethodMirror ctor = classMirror.declarations[classMirror.simpleName];
|
||||
return ctor.parameters;
|
||||
}
|
||||
}
|
||||
|
||||
final Reflector reflector = new Reflector();
|
||||
|
@ -14,14 +14,14 @@ class Reflector {
|
||||
return (args) => factoryFunction(...args);
|
||||
}
|
||||
|
||||
dependencies(type:Type):List {
|
||||
var p = type.parameters;
|
||||
if (p == undefined && type.length == 0) return [];
|
||||
if (p == undefined) throw new NoAnnotationError(type);
|
||||
return type.parameters.map((p) => this._extractToken(type, p));
|
||||
dependencies(typeOrFunc):List {
|
||||
var p = typeOrFunc.parameters;
|
||||
if (p == undefined && typeOrFunc.length == 0) return [];
|
||||
if (p == undefined) throw new NoAnnotationError(typeOrFunc);
|
||||
return typeOrFunc.parameters.map((p) => this._extractToken(typeOrFunc, p));
|
||||
}
|
||||
|
||||
_extractToken(constructedType:Type, annotations) {
|
||||
_extractToken(typeOrFunc, annotations) {
|
||||
var type;
|
||||
|
||||
for (var paramAnnotation of annotations) {
|
||||
@ -42,7 +42,7 @@ class Reflector {
|
||||
if (isPresent(type)) {
|
||||
return this._createDependency(type, false, false);
|
||||
} else {
|
||||
throw new NoAnnotationError(constructedType);
|
||||
throw new NoAnnotationError(typeOrFunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user