feat(injector): add support for default bindings

This commit is contained in:
vsavkin 2014-10-10 11:36:06 -04:00
parent ee1e54cf0a
commit f524a89cb6
3 changed files with 43 additions and 5 deletions

View File

@ -19,11 +19,12 @@ function _isWaiting(obj):boolean {
export class Injector { export class Injector {
constructor(bindings:List, parent:Injector = null) { constructor(bindings:List, {parent=null, defaultBindings=false}={}) {
var flatten = _flattenBindings(bindings, MapWrapper.create()); var flatten = _flattenBindings(bindings, MapWrapper.create());
this._bindings = this._createListOfBindings(flatten); this._bindings = this._createListOfBindings(flatten);
this._instances = this._createInstances(); this._instances = this._createInstances();
this._parent = parent; this._parent = parent;
this._defaultBindings = defaultBindings;
this._asyncStrategy = new _AsyncInjectorStrategy(this); this._asyncStrategy = new _AsyncInjectorStrategy(this);
this._syncStrategy = new _SyncInjectorStrategy(this); this._syncStrategy = new _SyncInjectorStrategy(this);
@ -38,7 +39,7 @@ export class Injector {
} }
createChild(bindings:List):Injector { createChild(bindings:List):Injector {
return new Injector(bindings, this); return new Injector(bindings, {parent: this});
} }
@ -92,8 +93,15 @@ export class Injector {
} }
_getBinding(key:Key) { _getBinding(key:Key) {
if (this._bindings.length <= key.id) return null; var binding = this._bindings.length <= key.id ?
return ListWrapper.get(this._bindings, key.id); null :
ListWrapper.get(this._bindings, key.id);
if (isBlank(binding) && this._defaultBindings) {
return bind(key.token).toClass(key.token);
} else {
return binding;
}
} }
_markAsConstructing(key:Key) { _markAsConstructing(key:Key) {

View File

@ -215,6 +215,25 @@ export function main() {
expect(injector.get(Car)).toBeAnInstanceOf(Car); expect(injector.get(Car)).toBeAnInstanceOf(Car);
}); });
describe("default bindings", function () {
it("should be used when no matching binding found", function () {
var injector = new Injector([], {defaultBindings: true});
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(Car);
});
it("should use the matching binding when it is available", function () {
var injector = new Injector([
bind(Car).toClass(SportsCar)
], {defaultBindings: true});
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(SportsCar);
});
});
describe("child", function () { describe("child", function () {
it('should load instances from parent injector', function () { it('should load instances from parent injector', function () {
@ -239,6 +258,17 @@ export function main() {
expect(engineFromParent).not.toBe(engineFromChild); expect(engineFromParent).not.toBe(engineFromChild);
expect(engineFromChild).toBeAnInstanceOf(TurboEngine); expect(engineFromChild).toBeAnInstanceOf(TurboEngine);
}); });
it("should create child injectors without default bindings", function () {
var parent = new Injector([], {defaultBindings: true});
var child = parent.createChild([]);
//child delegates to parent the creation of Car
var childCar = child.get(Car);
var parentCar = parent.get(Car);
expect(childCar).toBe(parentCar);
});
}); });
describe("lazy", function () { describe("lazy", function () {

View File

@ -62,7 +62,7 @@ export class ClassTransformer extends ParseTreeTransformer {
// so that we can use them to set the types of simple-assigned fields. // so that we can use them to set the types of simple-assigned fields.
elementTree.parameterList.parameters.forEach(function(p) { elementTree.parameterList.parameters.forEach(function(p) {
var binding = p.parameter.binding; var binding = p.parameter.binding;
if (binding.identifierToken) { if (binding && binding.identifierToken) {
argumentTypesMap[binding.identifierToken.value] = p.typeAnnotation; argumentTypesMap[binding.identifierToken.value] = p.typeAnnotation;
} }
}); });