feat(di): provide two ways to create an injector, resolved and unresolved

Add two factory static functions to Injector: resolveAndCreate and
fromResolvedBindings.

We want to avoid resolution and flattening every time we create a new
injector. This commit allows the user to cache resolved bindings and
reuse them.
This commit is contained in:
Yegor Jbanov
2015-04-10 17:05:31 -07:00
parent 6c8398df9b
commit 4a961f4ecb
24 changed files with 160 additions and 127 deletions
+19 -19
View File
@@ -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