Skip to content

Commit be1c2fc

Browse files
authored
Implements #505 (#512)
* Implemments #505 * Added docs for #505
1 parent 1410309 commit be1c2fc

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "inversify",
3-
"version": "3.2.0",
3+
"version": "3.3.0",
44
"description": "A powerful and lightweight inversion of control container for JavaScript and Node.js apps powered by TypeScript.",
55
"main": "lib/inversify.js",
66
"jsnext:main": "es/inversify.js",

src/container/container.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ class Container implements interfaces.Container {
254254
return this.getAllTagged<T>(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
255255
}
256256

257+
public resolve<T>(constructorFunction: interfaces.Newable<T>) {
258+
const tempContainer = new Container();
259+
tempContainer.bind<T>(constructorFunction).toSelf();
260+
tempContainer.parent = this;
261+
return tempContainer.get<T>(constructorFunction);
262+
}
263+
257264
// Prepares arguments required for resolution and
258265
// delegates resolution to _middleware if available
259266
// otherwise it delegates resoltion to _planAndResolve

src/interfaces/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ namespace interfaces {
174174
getNamed<T>(serviceIdentifier: ServiceIdentifier<T>, named: string|number|symbol): T;
175175
getTagged<T>(serviceIdentifier: ServiceIdentifier<T>, key: string|number|symbol, value: any): T;
176176
getAll<T>(serviceIdentifier: ServiceIdentifier<T>): T[];
177+
resolve<T>(constructorFunction: interfaces.Newable<T>): T;
177178
load(...modules: ContainerModule[]): void;
178179
unload(...modules: ContainerModule[]): void;
179180
applyCustomMetadataReader(metadataReader: MetadataReader): void;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from "chai";
2+
import { Container, injectable } from "../../src/inversify";
3+
4+
describe("Container.prototype.resolve", () => {
5+
6+
it("Should be able to resolve a class that has not binded", () => {
7+
8+
@injectable()
9+
class Katana {
10+
public hit() {
11+
return "cut!";
12+
}
13+
}
14+
15+
@injectable()
16+
class Ninja implements Ninja {
17+
public katana: Katana;
18+
public constructor(katana: Katana) {
19+
this.katana = katana;
20+
}
21+
public fight() { return this.katana.hit(); }
22+
}
23+
24+
const container = new Container();
25+
container.bind(Katana).toSelf();
26+
27+
const tryGet = () => container.get(Ninja);
28+
expect(tryGet).to.throw("No matching bindings found for serviceIdentifier: Ninja");
29+
30+
const ninja = container.resolve(Ninja);
31+
expect(ninja.fight()).to.eql("cut!");
32+
33+
});
34+
35+
});

wiki/container_api.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,36 @@ container.rebind<number>(TYPES.someType).toConstantValue(3);
278278
let values2 = container.getAll(TYPES.someType);
279279
expect(values2[0]).to.eq(3);
280280
expect(values2[1]).to.eq(undefined);
281-
```
281+
```
282+
283+
## container.resolve<T>(constructor: Newable<T>)
284+
Resolve is like `container.get<T>(serviceIdentifier: ServiceIdentifier<T>)` but it allows users to create an instance wven if no bindings have been declared:
285+
286+
```ts
287+
@injectable()
288+
class Katana {
289+
public hit() {
290+
return "cut!";
291+
}
292+
}
293+
294+
@injectable()
295+
class Ninja implements Ninja {
296+
public katana: Katana;
297+
public constructor(katana: Katana) {
298+
this.katana = katana;
299+
}
300+
public fight() { return this.katana.hit(); }
301+
}
302+
303+
const container = new Container();
304+
container.bind(Katana).toSelf();
305+
306+
const tryGet = () => container.get(Ninja);
307+
expect(tryGet).to.throw("No matching bindings found for serviceIdentifier: Ninja");
308+
309+
const ninja = container.resolve(Ninja);
310+
expect(ninja.fight()).to.eql("cut!");
311+
```
312+
313+
Please note that it only allows to skip declaring a binding for the root element in the dependency graph (composition root). All the sub-dependencies (e.g. `Katana` in the preceding example) will require a binding to be declared.

0 commit comments

Comments
 (0)