diff --git a/modules/angular2/docs/di/di.md b/modules/angular2/docs/di/di.md index f78d51ab99..a049bf8350 100644 --- a/modules/angular2/docs/di/di.md +++ b/modules/angular2/docs/di/di.md @@ -43,7 +43,7 @@ class Car { } } -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Car).toClass(Car), bind(Engine).toClass(Engine) ]); @@ -86,7 +86,7 @@ To avoid bugs make sure the registered objects have side-effect-free constructor Injectors are hierarchical. ``` -var child = injector.createChild([ +var child = injector.resolveAndCreateChild([ bind(Engine).toClass(TurboEngine) ]); @@ -99,21 +99,21 @@ var car = child.get(Car); // uses the Car binding from the parent injector and E You can bind to a class, a value, or a factory. It is also possible to alias existing bindings. ``` -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Car).toClass(Car), bind(Engine).toClass(Engine) ]); -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ Car, // syntax sugar for bind(Car).toClass(Car) Engine ]); -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Car).toValue(new Car(new Engine())) ]); -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Car).toFactory((e) => new Car(e), [Engine]), bind(Engine).toFactory(() => new Engine()) ]); @@ -122,7 +122,7 @@ var inj = new Injector([ You can bind any token. ``` -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Car).toFactory((e) => new Car(), ["engine!"]), bind("engine!").toClass(Engine) ]); @@ -131,7 +131,7 @@ var inj = new Injector([ If you want to alias an existing binding, you can do so using `toAlias`: ``` -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Engine).toClass(Engine), bind("engine!").toAlias(Engine) ]); @@ -152,7 +152,7 @@ The `someFactory` function does not have to know that it creates an object for ` Injector can create binding on the fly if we enable default bindings. ``` -var inj = new Injector([], {defaultBindings: true}); +var inj = Injector.resolveAndCreate([], {defaultBindings: true}); var car = inj.get(Car); //this works as if `bind(Car).toClass(Car)` and `bind(Engine).toClass(Engine)` were present. ``` @@ -226,7 +226,7 @@ class UserController { } } -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(() => fetchUsersUsingHttp().then((u) => new UserList(u))), UserController ]) @@ -252,7 +252,7 @@ class UserController { } } -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(() => fetchUsersUsingHttp().then((u) => new UserList(u))), UserController ]) @@ -276,7 +276,7 @@ class UserController { constructor(ul:UserList){} } -var inj = new Injector([UserList, UserController]); +var inj = Injector.resolveAndCreate([UserList, UserController]); var ctrl:UserController = inj.get(UserController); ``` @@ -290,7 +290,7 @@ class UserController { constructor(@InjectPromise(UserList) ul){} } -var inj = new Injector([UserList, UserController]); +var inj = Injector.resolveAndCreate([UserList, UserController]); var ctrl:UserController = inj.get(UserController); // UserController responsible for dealing with asynchrony. expect(ctrl.ul).toBePromise(); @@ -306,7 +306,7 @@ class UserController { constructor(ul:UserList){} } -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(() => fetchUsersUsingHttp().then((u) => new UserList(u))), UserController ]); @@ -331,7 +331,7 @@ class UserController { constructor(@InjectPromise(UserList) ul){} } -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(() => fetchUsersUsingHttp().then((u) => new UserList(u))), UserController ]); @@ -369,14 +369,14 @@ If we need a transient dependency, something that we want a new instance of ever We can create a child injector: ``` -var child = inj.createChild([MyClass]); +var child = inj.resolveAndCreateChild([MyClass]); child.get(MyClass); ``` Or we can register a factory function: ``` -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind('MyClassFactory').toFactory(dep => () => new MyClass(dep), [SomeDependency]) ]); @@ -393,7 +393,7 @@ expect(instance1).not.toBe(instance2); Most of the time we do not have to deal with keys. ``` -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(Engine).toFactory(() => new TurboEngine()) //the passed in token Engine gets mapped to a key ]); var engine = inj.get(Engine); //the passed in token Engine gets mapped to a key @@ -404,7 +404,7 @@ Now, the same example, but with keys ``` var ENGINE_KEY = Key.get(Engine); -var inj = new Injector([ +var inj = Injector.resolveAndCreate([ bind(ENGINE_KEY).toFactory(() => new TurboEngine()) // no mapping ]); var engine = inj.get(ENGINE_KEY); // no mapping diff --git a/modules/angular2/src/core/application.js b/modules/angular2/src/core/application.js index 0663e02b72..2856aab2e1 100644 --- a/modules/angular2/src/core/application.js +++ b/modules/angular2/src/core/application.js @@ -276,10 +276,10 @@ export function bootstrap(appComponentType: Type, } function _createAppInjector(appComponentType: Type, bindings: List, zone: VmTurnZone): Injector { - if (isBlank(_rootInjector)) _rootInjector = new Injector(_rootBindings); + if (isBlank(_rootInjector)) _rootInjector = Injector.resolveAndCreate(_rootBindings); var mergedBindings = isPresent(bindings) ? ListWrapper.concat(_injectorBindings(appComponentType), bindings) : _injectorBindings(appComponentType); ListWrapper.push(mergedBindings, bind(VmTurnZone).toValue(zone)); - return _rootInjector.createChild(mergedBindings); + return _rootInjector.resolveAndCreateChild(mergedBindings); } diff --git a/modules/angular2/src/core/compiler/dynamic_component_loader.js b/modules/angular2/src/core/compiler/dynamic_component_loader.js index 1d903e47ae..875da4b00e 100644 --- a/modules/angular2/src/core/compiler/dynamic_component_loader.js +++ b/modules/angular2/src/core/compiler/dynamic_component_loader.js @@ -80,7 +80,7 @@ export class DynamicComponentLoader { _componentAppInjector(location, injector, services) { var inj = isPresent(injector) ? injector : location.injector; - return isPresent(services) ? inj.createChild(services) : inj; + return isPresent(services) ? inj.resolveAndCreateChild(services) : inj; } _instantiateAndHydrateView(protoView, injector, hostElementInjector, context) { diff --git a/modules/angular2/src/core/compiler/view.js b/modules/angular2/src/core/compiler/view.js index c07b3224f1..ebd7ef7ee8 100644 --- a/modules/angular2/src/core/compiler/view.js +++ b/modules/angular2/src/core/compiler/view.js @@ -153,7 +153,7 @@ export class AppView { if (isPresent(componentDirective)) { var injectables = componentDirective.annotation.injectables; if (isPresent(injectables)) - shadowDomAppInjector = appInjector.createChild(injectables); + shadowDomAppInjector = appInjector.resolveAndCreateChild(injectables); else { shadowDomAppInjector = appInjector; } diff --git a/modules/angular2/src/di/binding.js b/modules/angular2/src/di/binding.js index 2efbb49257..2f4f37ef3a 100644 --- a/modules/angular2/src/di/binding.js +++ b/modules/angular2/src/di/binding.js @@ -94,7 +94,9 @@ export class Binding { for (var i = 0; i < bindings.length; i++) { var unresolved = bindings[i]; var resolved; - if (unresolved instanceof Type) { + if (unresolved instanceof ResolvedBinding) { + resolved = unresolved; // ha-ha! I'm easily amused + } else if (unresolved instanceof Type) { resolved = bind(unresolved).toClass(unresolved).resolve(); } else if (unresolved instanceof Binding) { resolved = unresolved.resolve(); diff --git a/modules/angular2/src/di/injector.js b/modules/angular2/src/di/injector.js index 5910769d39..7181719701 100644 --- a/modules/angular2/src/di/injector.js +++ b/modules/angular2/src/di/injector.js @@ -27,13 +27,39 @@ export class Injector { _defaultBindings:boolean; _asyncStrategy: _AsyncInjectorStrategy; _syncStrategy:_SyncInjectorStrategy; - constructor(bindings:List, {parent=null, defaultBindings=false}={}) { + + /** + * Creates/looks up factory functions and dependencies from binding + * declarations and flattens bindings into a single [List]. + */ + static resolve(bindings:List/**/):List { var flatten = _flattenBindings(Binding.resolveAll(bindings), MapWrapper.create()); - this._bindings = this._createListOfBindings(flatten); + return _createListOfBindings(flatten); + } + + /** + * Resolves bindings and creates an injector based on those bindings. This function is slower than the + * corresponding [fromResolvedBindings] because it needs to resolve bindings. Prefer [fromResolvedBindings] + * in performance-critical code that creates lots of injectors. + */ + static resolveAndCreate(bindings:List/**/, {defaultBindings=false}={}) { + return new Injector(Injector.resolve(bindings), null, defaultBindings); + } + + /** + * Creates an injector from previously resolved bindings. This bypasses a lot + * of computation and is the recommended way to construct injectors in + * performance-sensitive parts. + */ + static fromResolvedBindings(bindings:List, {defaultBindings=false}={}) { + return new Injector(bindings, null, defaultBindings); + } + + constructor(bindings:List, parent:Injector, defaultBindings:boolean) { + this._bindings = bindings; this._instances = this._createInstances(); this._parent = parent; this._defaultBindings = defaultBindings; - this._asyncStrategy = new _AsyncInjectorStrategy(this); this._syncStrategy = new _SyncInjectorStrategy(this); } @@ -50,15 +76,12 @@ export class Injector { return this._getByKey(Key.get(token), true, false, false); } - createChild(bindings:List):Injector { - return new Injector(bindings, {parent: this}); + resolveAndCreateChild(bindings:List/**/):Injector { + return new Injector(Injector.resolve(bindings), this, false); } - - _createListOfBindings(flattenBindings):List { - var bindings = ListWrapper.createFixedSize(Key.numberOfKeys + 1); - MapWrapper.forEach(flattenBindings, (v, keyId) => bindings[keyId] = v); - return bindings; + createChildFromResolved(bindings:List):Injector { + return new Injector(bindings, this, false); } _createInstances():List { @@ -244,6 +267,14 @@ class _AsyncInjectorStrategy { } } +function _createListOfBindings(flattenBindings):List { + var bindings = ListWrapper.createFixedSize(Key.numberOfKeys + 1); + MapWrapper.forEach(flattenBindings, (v, keyId) => bindings[keyId] = v); + return bindings; +} + + + function _flattenBindings(bindings:List, res:Map) { ListWrapper.forEach(bindings, function (b) { if (b instanceof ResolvedBinding) { diff --git a/modules/angular2/src/test_lib/test_injector.js b/modules/angular2/src/test_lib/test_injector.js index 01dd910700..ce1ef162d3 100644 --- a/modules/angular2/src/test_lib/test_injector.js +++ b/modules/angular2/src/test_lib/test_injector.js @@ -110,8 +110,8 @@ function _getAppBindings() { } export function createTestInjector(bindings: List) { - var rootInjector = new Injector(_getRootBindings()); - return rootInjector.createChild(ListWrapper.concat(_getAppBindings(), bindings)); + var rootInjector = Injector.resolveAndCreate(_getRootBindings()); + return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), bindings)); } /** diff --git a/modules/angular2/test/core/compiler/element_injector_spec.js b/modules/angular2/test/core/compiler/element_injector_spec.js index 968db80bb3..8c6fee2ef8 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.js +++ b/modules/angular2/test/core/compiler/element_injector_spec.js @@ -209,7 +209,7 @@ class TestNode extends TreeNode { export function main() { var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null, null); - var appInjector = new Injector([]); + var appInjector = Injector.resolveAndCreate([]); function humanize(tree, names:List) { var lookupName = (item) => @@ -236,7 +236,7 @@ export function main() { function parentChildInjectors(parentBindings, childBindings, parentPreBuildObjects = null) { if (isBlank(parentPreBuildObjects)) parentPreBuildObjects = defaultPreBuiltObjects; - var inj = new Injector([]); + var inj = Injector.resolveAndCreate([]); var protoParent = new ProtoElementInjector(null, 0, parentBindings); var parent = protoParent.instantiate(null); @@ -253,8 +253,8 @@ export function main() { function hostShadowInjectors(hostBindings, shadowBindings, hostPreBuildObjects = null) { if (isBlank(hostPreBuildObjects)) hostPreBuildObjects = defaultPreBuiltObjects; - var inj = new Injector([]); - var shadowInj = inj.createChild([]); + var inj = Injector.resolveAndCreate([]); + var shadowInj = inj.resolveAndCreateChild([]); var protoParent = new ProtoElementInjector(null, 0, hostBindings, true); var host = protoParent.instantiate(null); @@ -455,7 +455,7 @@ export function main() { }); it("should instantiate directives that depend on app services", function () { - var appInjector = new Injector([ + var appInjector = Injector.resolveAndCreate([ bind("service").toValue("service") ]); var inj = injector([NeedsService], appInjector); @@ -487,7 +487,7 @@ export function main() { }); it("should instantiate component directives that depend on app services in the shadow app injector", () => { - var shadowAppInjector = new Injector([ + var shadowAppInjector = Injector.resolveAndCreate([ bind("service").toValue("service") ]); var inj = injector([NeedsService], null, shadowAppInjector); @@ -498,7 +498,7 @@ export function main() { }); it("should not instantiate other directives that depend on app services in the shadow app injector", () => { - var shadowAppInjector = new Injector([ + var shadowAppInjector = Injector.resolveAndCreate([ bind("service").toValue("service") ]); expect(() => { @@ -507,7 +507,7 @@ export function main() { }); it("should return app services", function () { - var appInjector = new Injector([ + var appInjector = Injector.resolveAndCreate([ bind("service").toValue("service") ]); var inj = injector([], appInjector); @@ -687,7 +687,7 @@ export function main() { it("should inject services of the dynamically-loaded component", () => { var inj = injector([]); - var appInjector = new Injector([bind("service").toValue("Service")]); + var appInjector = Injector.resolveAndCreate([bind("service").toValue("Service")]); inj.dynamicallyCreateComponent(NeedsService, null, appInjector); expect(inj.getDynamicallyLoadedComponent().service).toEqual("Service"); }); @@ -844,8 +844,8 @@ export function main() { var parent = protoParent.instantiate(null); var child = protoChild.instantiate(parent); - parent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child.instantiateDirectives(new Injector([]), null, null, preBuildObjects); + parent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); expectDirectives(parent.get(NeedsQuery).query, CountingDirective, [0,1]); }); @@ -856,8 +856,8 @@ export function main() { var parent = protoParent.instantiate(null); var child = protoChild.instantiate(parent); - parent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child.instantiateDirectives(new Injector([]), null, null, preBuildObjects); + parent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); child.unlink(); @@ -873,9 +873,9 @@ export function main() { var child1 = protoChild1.instantiate(parent); var child2 = protoChild2.instantiate(parent); - parent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child1.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child2.instantiateDirectives(new Injector([]), null, null, preBuildObjects); + parent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child1.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child2.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); child1.unlink(); child1.link(parent); @@ -893,9 +893,9 @@ export function main() { var child1 = protoChild1.instantiate(parent); var child2 = protoChild2.instantiate(parent); - parent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child1.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child2.instantiateDirectives(new Injector([]), null, null, preBuildObjects); + parent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child1.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child2.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); child2.unlink(); child2.linkAfter(parent, null); @@ -913,9 +913,9 @@ export function main() { var parent = protoParent.instantiate(grandParent); var child = protoChild.instantiate(parent); - grandParent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - parent.instantiateDirectives(new Injector([]), null, null, preBuildObjects); - child.instantiateDirectives(new Injector([]), null, null, preBuildObjects); + grandParent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + parent.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); + child.instantiateDirectives(Injector.resolveAndCreate([]), null, null, preBuildObjects); var queryList1 = grandParent.get(NeedsQuery).query; var queryList2 = parent.get(NeedsQuery).query; diff --git a/modules/angular2/test/di/async_spec.js b/modules/angular2/test/di/async_spec.js index c715bf3bf4..841fe32013 100644 --- a/modules/angular2/test/di/async_spec.js +++ b/modules/angular2/test/di/async_spec.js @@ -41,7 +41,7 @@ export function main() { describe("asyncGet", function () { it('should return a promise', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers) ]); var p = injector.asyncGet(UserList); @@ -49,7 +49,7 @@ export function main() { }); it('should return a promise when the binding is sync', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ SynchronousUserList ]); var p = injector.asyncGet(SynchronousUserList); @@ -57,7 +57,7 @@ export function main() { }); it("should return a promise when the binding is sync (from cache)", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ UserList ]); expect(injector.get(UserList)).toBeAnInstanceOf(UserList); @@ -65,7 +65,7 @@ export function main() { }); it('should return the injector', inject([AsyncTestCompleter], (async) => { - var injector = new Injector([]); + var injector = Injector.resolveAndCreate([]); var p = injector.asyncGet(Injector); p.then(function (injector) { expect(injector).toBe(injector); @@ -75,7 +75,7 @@ export function main() { it('should return a promise when instantiating a sync binding ' + 'with an async dependency', inject([AsyncTestCompleter], (async) => { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers), UserController ]); @@ -88,7 +88,7 @@ export function main() { })); it("should create only one instance (async + async)", inject([AsyncTestCompleter], (async) => { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers) ]); @@ -102,7 +102,7 @@ export function main() { })); it("should create only one instance (sync + async)", inject([AsyncTestCompleter], (async) => { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ UserList ]); @@ -119,7 +119,7 @@ export function main() { })); it('should show the full path when error happens in a constructor', inject([AsyncTestCompleter], (async) => { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ UserController, bind(UserList).toAsyncFactory(function () { throw "Broken UserList"; @@ -136,7 +136,7 @@ export function main() { describe("get", function () { it('should throw when instantiating an async binding', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers) ]); @@ -145,7 +145,7 @@ export function main() { }); it('should throw when instantiating a sync binding with an async dependency', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers), UserController ]); @@ -156,7 +156,7 @@ export function main() { it('should not throw when instantiating a sync binding with a resolved async dependency', inject([AsyncTestCompleter], (async) => { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers), UserController ]); @@ -168,7 +168,7 @@ export function main() { })); it('should resolve synchronously when an async dependency requested as a promise', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toAsyncFactory(fetchUsers), AsyncUserController ]); @@ -179,7 +179,7 @@ export function main() { }); it('should wrap sync dependencies into promises if required', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(UserList).toFactory(() => new UserList()), AsyncUserController ]); diff --git a/modules/angular2/test/di/injector_spec.js b/modules/angular2/test/di/injector_spec.js index e030a60da6..21d8a0a5e6 100644 --- a/modules/angular2/test/di/injector_spec.js +++ b/modules/angular2/test/di/injector_spec.js @@ -75,14 +75,14 @@ class NoAnnotations { export function main() { describe('injector', function () { it('should instantiate a class without dependencies', function () { - var injector = new Injector([Engine]); + var injector = Injector.resolveAndCreate([Engine]); var engine = injector.get(Engine); expect(engine).toBeAnInstanceOf(Engine); }); it('should resolve dependencies based on type information', function () { - var injector = new Injector([Engine, Car]); + var injector = Injector.resolveAndCreate([Engine, Car]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(Car); @@ -90,7 +90,7 @@ export function main() { }); it('should resolve dependencies based on @Inject annotation', function () { - var injector = new Injector([TurboEngine, Engine, CarWithInject]); + var injector = Injector.resolveAndCreate([TurboEngine, Engine, CarWithInject]); var car = injector.get(CarWithInject); expect(car).toBeAnInstanceOf(CarWithInject); @@ -98,12 +98,12 @@ export function main() { }); it('should throw when no type and not @Inject', function () { - expect(() => new Injector([NoAnnotations])).toThrowError( + expect(() => Injector.resolveAndCreate([NoAnnotations])).toThrowError( 'Cannot resolve all parameters for NoAnnotations'); }); it('should cache instances', function () { - var injector = new Injector([Engine]); + var injector = Injector.resolveAndCreate([Engine]); var e1 = injector.get(Engine); var e2 = injector.get(Engine); @@ -112,7 +112,7 @@ export function main() { }); it('should bind to a value', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(Engine).toValue("fake engine") ]); @@ -125,7 +125,7 @@ export function main() { return new SportsCar(e); } - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Engine, bind(Car).toFactory(sportsCarFactory) ]); @@ -136,7 +136,7 @@ export function main() { }); it('should bind to an alias', function() { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Engine, bind(SportsCar).toClass(SportsCar), bind(Car).toAlias(SportsCar) @@ -149,14 +149,14 @@ export function main() { }); it('should throw when the aliased binding does not exist', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind('car').toAlias(SportsCar) ]); expect(() => injector.get('car')).toThrowError('No provider for SportsCar! (car -> SportsCar)'); }); it('should support overriding factory dependencies', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Engine, bind(Car).toFactory((e) => new SportsCar(e), [Engine]) ]); @@ -167,7 +167,7 @@ export function main() { }); it('should support optional dependencies', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ CarWithOptionalEngine ]); @@ -176,7 +176,7 @@ export function main() { }); it("should flatten passed-in bindings", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ [[Engine, Car]] ]); @@ -186,7 +186,7 @@ export function main() { it("should use the last binding "+ "when there are mutliple bindings for same token", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(Engine).toClass(Engine), bind(Engine).toClass(TurboEngine) ]); @@ -195,7 +195,7 @@ export function main() { }); it('should use non-type tokens', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind('token').toValue('value') ]); @@ -203,30 +203,30 @@ export function main() { }); it('should throw when given invalid bindings', function () { - expect(() => new Injector(["blah"])).toThrowError('Invalid binding blah'); - expect(() => new Injector([bind("blah")])).toThrowError('Invalid binding blah'); + expect(() => Injector.resolveAndCreate(["blah"])).toThrowError('Invalid binding blah'); + expect(() => Injector.resolveAndCreate([bind("blah")])).toThrowError('Invalid binding blah'); }); it('should provide itself', function () { - var parent = new Injector([]); - var child = parent.createChild([]); + var parent = Injector.resolveAndCreate([]); + var child = parent.resolveAndCreateChild([]); expect(child.get(Injector)).toBe(child); }); it('should throw when no provider defined', function () { - var injector = new Injector([]); + var injector = Injector.resolveAndCreate([]); expect(() => injector.get('NonExisting')).toThrowError('No provider for NonExisting!'); }); it('should show the full path when no provider', function () { - var injector = new Injector([CarWithDashboard, Engine, Dashboard]); + var injector = Injector.resolveAndCreate([CarWithDashboard, Engine, Dashboard]); expect(() => injector.get(CarWithDashboard)). toThrowError('No provider for DashboardSoftware! (CarWithDashboard -> Dashboard -> DashboardSoftware)'); }); it('should throw when trying to instantiate a cyclic dependency', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Car, bind(Engine).toClass(CyclicEngine) ]); @@ -239,7 +239,7 @@ export function main() { }); it('should show the full path when error happens in a constructor', function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Car, bind(Engine).toClass(BrokenEngine) ]); @@ -255,7 +255,7 @@ export function main() { it('should instantiate an object after a failed attempt', function () { var isBroken = true; - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Car, bind(Engine).toFactory(() => isBroken ? new BrokenEngine() : new Engine()) ]); @@ -268,13 +268,13 @@ export function main() { }); it('should support null values', () => { - var injector = new Injector([bind('null').toValue(null)]); + var injector = Injector.resolveAndCreate([bind('null').toValue(null)]); expect(injector.get('null')).toBe(null); }); describe("default bindings", function () { it("should be used when no matching binding found", function () { - var injector = new Injector([], {defaultBindings: true}); + var injector = Injector.resolveAndCreate([], {defaultBindings: true}); var car = injector.get(Car); @@ -282,7 +282,7 @@ export function main() { }); it("should use the matching binding when it is available", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ bind(Car).toClass(SportsCar) ], {defaultBindings: true}); @@ -294,8 +294,8 @@ export function main() { describe("child", function () { it('should load instances from parent injector', function () { - var parent = new Injector([Engine]); - var child = parent.createChild([]); + var parent = Injector.resolveAndCreate([Engine]); + var child = parent.resolveAndCreateChild([]); var engineFromParent = parent.get(Engine); var engineFromChild = child.get(Engine); @@ -304,10 +304,10 @@ export function main() { }); it("should not use the child bindings when resolving the dependencies of a parent binding", function () { - var parent = new Injector([ + var parent = Injector.resolveAndCreate([ Car, Engine ]); - var child = parent.createChild([ + var child = parent.resolveAndCreateChild([ bind(Engine).toClass(TurboEngine) ]); @@ -316,8 +316,8 @@ export function main() { }); it('should create new instance in a child injector', function () { - var parent = new Injector([Engine]); - var child = parent.createChild([ + var parent = Injector.resolveAndCreate([Engine]); + var child = parent.resolveAndCreateChild([ bind(Engine).toClass(TurboEngine) ]); @@ -329,8 +329,8 @@ export function main() { }); it("should create child injectors without default bindings", function () { - var parent = new Injector([], {defaultBindings: true}); - var child = parent.createChild([]); + var parent = Injector.resolveAndCreate([], {defaultBindings: true}); + var child = parent.resolveAndCreateChild([]); //child delegates to parent the creation of Car var childCar = child.get(Car); @@ -342,7 +342,7 @@ export function main() { describe("lazy", function () { it("should create dependencies lazily", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Engine, CarWithLazyEngine ]); @@ -352,7 +352,7 @@ export function main() { }); it("should cache instance created lazily", function () { - var injector = new Injector([ + var injector = Injector.resolveAndCreate([ Engine, CarWithLazyEngine ]); diff --git a/modules/benchmarks/src/di/di_benchmark.js b/modules/benchmarks/src/di/di_benchmark.js index c8ee1d2b77..28038ea5ac 100644 --- a/modules/benchmarks/src/di/di_benchmark.js +++ b/modules/benchmarks/src/di/di_benchmark.js @@ -16,16 +16,16 @@ export function main() { setupReflector(); var bindings = [A, B, C, D, E]; - var injector = new Injector(bindings); + var injector = Injector.resolveAndCreate(bindings); var D_KEY = Key.get(D); var E_KEY = Key.get(E); var childInjector = injector. - createChild([]). - createChild([]). - createChild([]). - createChild([]). - createChild([]); + resolveAndCreateChild([]). + resolveAndCreateChild([]). + resolveAndCreateChild([]). + resolveAndCreateChild([]). + resolveAndCreateChild([]); var variousBindings = [ A, @@ -56,7 +56,7 @@ export function main() { function instantiate() { for (var i = 0; i < iterations; ++i) { - var child = injector.createChild([E]); + var child = injector.resolveAndCreateChild([E]); child.get(E); } } diff --git a/modules/benchmarks/src/element_injector/element_injector_benchmark.js b/modules/benchmarks/src/element_injector/element_injector_benchmark.js index 47fc6e5a7a..660db46a93 100644 --- a/modules/benchmarks/src/element_injector/element_injector_benchmark.js +++ b/modules/benchmarks/src/element_injector/element_injector_benchmark.js @@ -12,7 +12,7 @@ export function main() { var iterations = getIntParameter('iterations'); reflector.reflectionCapabilities = new ReflectionCapabilities(); - var appInjector = new Injector([]); + var appInjector = Injector.resolveAndCreate([]); var bindings = [A, B, C]; var proto = new ProtoElementInjector(null, 0, bindings); diff --git a/modules/benchpress/src/runner.js b/modules/benchpress/src/runner.js index f64bae1ac2..e1eac007d2 100644 --- a/modules/benchpress/src/runner.js +++ b/modules/benchpress/src/runner.js @@ -50,7 +50,7 @@ export class Runner { if (isPresent(bindings)) { ListWrapper.push(sampleBindings, bindings); } - return new Injector(sampleBindings).asyncGet(Sampler) + return Injector.resolveAndCreate(sampleBindings).asyncGet(Sampler) .then( (sampler) => sampler.sample() ); } } diff --git a/modules/benchpress/test/metric/multi_metric_spec.js b/modules/benchpress/test/metric/multi_metric_spec.js index f6911de9d0..1a2a50a207 100644 --- a/modules/benchpress/test/metric/multi_metric_spec.js +++ b/modules/benchpress/test/metric/multi_metric_spec.js @@ -18,7 +18,7 @@ import { Metric, MultiMetric, bind, Injector } from 'benchpress/common'; export function main() { function createMetric(ids) { - return new Injector([ + return Injector.resolveAndCreate([ ListWrapper.map(ids, (id) => bind(id).toValue(new MockMetric(id)) ), MultiMetric.createBindings(ids) ]).asyncGet(MultiMetric); diff --git a/modules/benchpress/test/metric/perflog_metric_spec.js b/modules/benchpress/test/metric/perflog_metric_spec.js index b877bc4ce5..e9c4696c36 100644 --- a/modules/benchpress/test/metric/perflog_metric_spec.js +++ b/modules/benchpress/test/metric/perflog_metric_spec.js @@ -45,7 +45,7 @@ export function main() { }), bind(WebDriverExtension).toValue(new MockDriverExtension(perfLogs, commandLog, perfLogFeatures)) ]; - return new Injector(bindings).get(PerflogMetric); + return Injector.resolveAndCreate(bindings).get(PerflogMetric); } describe('perflog metric', () => { diff --git a/modules/benchpress/test/reporter/console_reporter_spec.js b/modules/benchpress/test/reporter/console_reporter_spec.js index 05866b617e..a76a7cb262 100644 --- a/modules/benchpress/test/reporter/console_reporter_spec.js +++ b/modules/benchpress/test/reporter/console_reporter_spec.js @@ -29,7 +29,7 @@ export function main() { if (isPresent(columnWidth)) { ListWrapper.push(bindings, bind(ConsoleReporter.COLUMN_WIDTH).toValue(columnWidth)); } - reporter = new Injector(bindings).get(ConsoleReporter); + reporter = Injector.resolveAndCreate(bindings).get(ConsoleReporter); } it('should print the sample id, description and table header', () => { diff --git a/modules/benchpress/test/reporter/json_file_reporter_spec.js b/modules/benchpress/test/reporter/json_file_reporter_spec.js index 16f4a44e01..57aaf4d30c 100644 --- a/modules/benchpress/test/reporter/json_file_reporter_spec.js +++ b/modules/benchpress/test/reporter/json_file_reporter_spec.js @@ -42,7 +42,7 @@ export function main() { return PromiseWrapper.resolve(null); }) ]; - return new Injector(bindings).get(JsonFileReporter); + return Injector.resolveAndCreate(bindings).get(JsonFileReporter); } it('should write all data into a file', inject([AsyncTestCompleter], (async) => { diff --git a/modules/benchpress/test/reporter/multi_reporter_spec.js b/modules/benchpress/test/reporter/multi_reporter_spec.js index 06ab013205..7c7c78d7a8 100644 --- a/modules/benchpress/test/reporter/multi_reporter_spec.js +++ b/modules/benchpress/test/reporter/multi_reporter_spec.js @@ -19,7 +19,7 @@ import { Reporter, MultiReporter, bind, Injector, MeasureValues } from 'benchpre export function main() { function createReporters(ids) { - return new Injector([ + return Injector.resolveAndCreate([ ListWrapper.map(ids, (id) => bind(id).toValue(new MockReporter(id)) ), MultiReporter.createBindings(ids) ]).asyncGet(MultiReporter); diff --git a/modules/benchpress/test/sampler_spec.js b/modules/benchpress/test/sampler_spec.js index d6da57f7f9..b941d0023b 100644 --- a/modules/benchpress/test/sampler_spec.js +++ b/modules/benchpress/test/sampler_spec.js @@ -68,7 +68,7 @@ export function main() { ListWrapper.push(bindings, bind(Options.FORCE_GC).toValue(forceGc)); } - sampler = new Injector(bindings).get(Sampler); + sampler = Injector.resolveAndCreate(bindings).get(Sampler); } it('should call the prepare and execute callbacks using WebDriverAdapter.waitFor', inject([AsyncTestCompleter], (async) => { diff --git a/modules/benchpress/test/validator/regression_slope_validator_spec.js b/modules/benchpress/test/validator/regression_slope_validator_spec.js index 4bdef96581..775a3e08b5 100644 --- a/modules/benchpress/test/validator/regression_slope_validator_spec.js +++ b/modules/benchpress/test/validator/regression_slope_validator_spec.js @@ -11,7 +11,7 @@ export function main() { var validator; function createValidator({size, metric}) { - validator = new Injector([ + validator = Injector.resolveAndCreate([ RegressionSlopeValidator.BINDINGS, bind(RegressionSlopeValidator.METRIC).toValue(metric), bind(RegressionSlopeValidator.SAMPLE_SIZE).toValue(size) diff --git a/modules/benchpress/test/validator/size_validator_spec.js b/modules/benchpress/test/validator/size_validator_spec.js index 1d6e271d70..e5e1533d0b 100644 --- a/modules/benchpress/test/validator/size_validator_spec.js +++ b/modules/benchpress/test/validator/size_validator_spec.js @@ -11,7 +11,7 @@ export function main() { var validator; function createValidator(size) { - validator = new Injector([ + validator = Injector.resolveAndCreate([ SizeValidator.BINDINGS, bind(SizeValidator.SAMPLE_SIZE).toValue(size) ]).get(SizeValidator); diff --git a/modules/benchpress/test/web_driver_extension_spec.js b/modules/benchpress/test/web_driver_extension_spec.js index 5c609d6cae..7d0e84ee28 100644 --- a/modules/benchpress/test/web_driver_extension_spec.js +++ b/modules/benchpress/test/web_driver_extension_spec.js @@ -19,7 +19,7 @@ import { WebDriverExtension, bind, Injector, Options } from 'benchpress/common'; export function main() { function createExtension(ids, caps) { - return new Injector([ + return Injector.resolveAndCreate([ ListWrapper.map(ids, (id) => bind(id).toValue(new MockExtension(id)) ), bind(Options.CAPABILITIES).toValue(caps), WebDriverExtension.bindTo(ids) diff --git a/modules/benchpress/test/webdriver/chrome_driver_extension_spec.js b/modules/benchpress/test/webdriver/chrome_driver_extension_spec.js index cb8f665570..fc85c33cd5 100644 --- a/modules/benchpress/test/webdriver/chrome_driver_extension_spec.js +++ b/modules/benchpress/test/webdriver/chrome_driver_extension_spec.js @@ -38,7 +38,7 @@ export function main() { perfRecords = []; } log = []; - extension = new Injector([ + extension = Injector.resolveAndCreate([ ChromeDriverExtension.BINDINGS, bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords, messageMethod)) ]).get(ChromeDriverExtension); diff --git a/modules/benchpress/test/webdriver/ios_driver_extension_spec.js b/modules/benchpress/test/webdriver/ios_driver_extension_spec.js index 0d43707a0e..5ddaf35169 100644 --- a/modules/benchpress/test/webdriver/ios_driver_extension_spec.js +++ b/modules/benchpress/test/webdriver/ios_driver_extension_spec.js @@ -34,7 +34,7 @@ export function main() { perfRecords = []; } log = []; - extension = new Injector([ + extension = Injector.resolveAndCreate([ IOsDriverExtension.BINDINGS, bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords)) ]).get(IOsDriverExtension);