diff --git a/modules/di/src/injector.js b/modules/di/src/injector.js index 93270c17c0..d0d7a0fe06 100644 --- a/modules/di/src/injector.js +++ b/modules/di/src/injector.js @@ -19,11 +19,12 @@ function _isWaiting(obj):boolean { export class Injector { - constructor(bindings:List, parent:Injector = null) { + constructor(bindings:List, {parent=null, defaultBindings=false}={}) { var flatten = _flattenBindings(bindings, MapWrapper.create()); this._bindings = this._createListOfBindings(flatten); this._instances = this._createInstances(); this._parent = parent; + this._defaultBindings = defaultBindings; this._asyncStrategy = new _AsyncInjectorStrategy(this); this._syncStrategy = new _SyncInjectorStrategy(this); @@ -38,7 +39,7 @@ export class 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) { - if (this._bindings.length <= key.id) return null; - return ListWrapper.get(this._bindings, key.id); + var binding = this._bindings.length <= 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) { diff --git a/modules/di/test/di/injector_spec.js b/modules/di/test/di/injector_spec.js index 097952a4af..ed9fe97fc8 100644 --- a/modules/di/test/di/injector_spec.js +++ b/modules/di/test/di/injector_spec.js @@ -215,6 +215,25 @@ export function main() { 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 () { it('should load instances from parent injector', function () { @@ -239,6 +258,17 @@ export function main() { expect(engineFromParent).not.toBe(engineFromChild); 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 () { diff --git a/tools/transpiler/src/codegeneration/ClassTransformer.js b/tools/transpiler/src/codegeneration/ClassTransformer.js index a61d73c4e6..d4cf23065b 100644 --- a/tools/transpiler/src/codegeneration/ClassTransformer.js +++ b/tools/transpiler/src/codegeneration/ClassTransformer.js @@ -62,7 +62,7 @@ export class ClassTransformer extends ParseTreeTransformer { // so that we can use them to set the types of simple-assigned fields. elementTree.parameterList.parameters.forEach(function(p) { var binding = p.parameter.binding; - if (binding.identifierToken) { + if (binding && binding.identifierToken) { argumentTypesMap[binding.identifierToken.value] = p.typeAnnotation; } });