Skip to content

Commit f524a89

Browse files
committed
feat(injector): add support for default bindings
1 parent ee1e54c commit f524a89

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

modules/di/src/injector.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ function _isWaiting(obj):boolean {
1919

2020

2121
export class Injector {
22-
constructor(bindings:List, parent:Injector = null) {
22+
constructor(bindings:List, {parent=null, defaultBindings=false}={}) {
2323
var flatten = _flattenBindings(bindings, MapWrapper.create());
2424
this._bindings = this._createListOfBindings(flatten);
2525
this._instances = this._createInstances();
2626
this._parent = parent;
27+
this._defaultBindings = defaultBindings;
2728

2829
this._asyncStrategy = new _AsyncInjectorStrategy(this);
2930
this._syncStrategy = new _SyncInjectorStrategy(this);
@@ -38,7 +39,7 @@ export class Injector {
3839
}
3940

4041
createChild(bindings:List):Injector {
41-
return new Injector(bindings, this);
42+
return new Injector(bindings, {parent: this});
4243
}
4344

4445

@@ -92,8 +93,15 @@ export class Injector {
9293
}
9394

9495
_getBinding(key:Key) {
95-
if (this._bindings.length <= key.id) return null;
96-
return ListWrapper.get(this._bindings, key.id);
96+
var binding = this._bindings.length <= key.id ?
97+
null :
98+
ListWrapper.get(this._bindings, key.id);
99+
100+
if (isBlank(binding) && this._defaultBindings) {
101+
return bind(key.token).toClass(key.token);
102+
} else {
103+
return binding;
104+
}
97105
}
98106

99107
_markAsConstructing(key:Key) {

modules/di/test/di/injector_spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ export function main() {
215215
expect(injector.get(Car)).toBeAnInstanceOf(Car);
216216
});
217217

218+
describe("default bindings", function () {
219+
it("should be used when no matching binding found", function () {
220+
var injector = new Injector([], {defaultBindings: true});
221+
222+
var car = injector.get(Car);
223+
224+
expect(car).toBeAnInstanceOf(Car);
225+
});
226+
227+
it("should use the matching binding when it is available", function () {
228+
var injector = new Injector([
229+
bind(Car).toClass(SportsCar)
230+
], {defaultBindings: true});
231+
232+
var car = injector.get(Car);
233+
234+
expect(car).toBeAnInstanceOf(SportsCar);
235+
});
236+
});
218237

219238
describe("child", function () {
220239
it('should load instances from parent injector', function () {
@@ -239,6 +258,17 @@ export function main() {
239258
expect(engineFromParent).not.toBe(engineFromChild);
240259
expect(engineFromChild).toBeAnInstanceOf(TurboEngine);
241260
});
261+
262+
it("should create child injectors without default bindings", function () {
263+
var parent = new Injector([], {defaultBindings: true});
264+
var child = parent.createChild([]);
265+
266+
//child delegates to parent the creation of Car
267+
var childCar = child.get(Car);
268+
var parentCar = parent.get(Car);
269+
270+
expect(childCar).toBe(parentCar);
271+
});
242272
});
243273

244274
describe("lazy", function () {

tools/transpiler/src/codegeneration/ClassTransformer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class ClassTransformer extends ParseTreeTransformer {
6262
// so that we can use them to set the types of simple-assigned fields.
6363
elementTree.parameterList.parameters.forEach(function(p) {
6464
var binding = p.parameter.binding;
65-
if (binding.identifierToken) {
65+
if (binding && binding.identifierToken) {
6666
argumentTypesMap[binding.identifierToken.value] = p.typeAnnotation;
6767
}
6868
});

0 commit comments

Comments
 (0)