From 0d87fafc45887332a6e37e27602b97a298098c68 Mon Sep 17 00:00:00 2001 From: "Remo H. Jansen" Date: Thu, 25 Aug 2016 08:50:13 +0100 Subject: [PATCH] Implements #348 (#349) * Fixed #345 * Implemented #348 * added docs --- src/kernel/kernel.ts | 15 +++++++ test/kernel/kernel.test.ts | 54 ++++++++++++++++++++++++ wiki/get_all_named_tagged.md | 79 +++++++++++++++++++++++++++++++----- 3 files changed, 138 insertions(+), 10 deletions(-) diff --git a/src/kernel/kernel.ts b/src/kernel/kernel.ts index e1551d54..9933d3a6 100644 --- a/src/kernel/kernel.ts +++ b/src/kernel/kernel.ts @@ -168,6 +168,21 @@ class Kernel implements interfaces.Kernel { }); } + public getAllNamed(serviceIdentifier: interfaces.ServiceIdentifier, named: string): T[] { + return this.getAllTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named); + } + + public getAllTagged(serviceIdentifier: interfaces.ServiceIdentifier, key: string, value: any): T[] { + let metadata = new Metadata(key, value); + let target = new Target(null, serviceIdentifier, metadata); + return this._get({ + contextInterceptor: (context: interfaces.Context) => { return context; }, + multiInject: true, + serviceIdentifier: serviceIdentifier, + target: target + }); + } + public set parent (kernel: interfaces.Kernel) { this._parentKernel = kernel; } diff --git a/test/kernel/kernel.test.ts b/test/kernel/kernel.test.ts index d1ea4c2d..6fdaf47f 100644 --- a/test/kernel/kernel.test.ts +++ b/test/kernel/kernel.test.ts @@ -550,4 +550,58 @@ describe("Kernel", () => { expect(secondChildKernel.get(weaponIdentifier)).to.be.instanceOf(DivineRapier); }); + it("Should be able to resolve named multi-injection", () => { + + let kernel = new Kernel(); + + interface Intl { + hello?: string; + goodbye?: string; + } + + kernel.bind("Intl").toConstantValue({ hello: "bonjour" }).whenTargetNamed("fr"); + kernel.bind("Intl").toConstantValue({ goodbye: "au revoir" }).whenTargetNamed("fr"); + + kernel.bind("Intl").toConstantValue({ hello: "hola" }).whenTargetNamed("es"); + kernel.bind("Intl").toConstantValue({ goodbye: "adios" }).whenTargetNamed("es"); + + let fr = kernel.getAllNamed("Intl", "fr"); + expect(fr.length).to.eql(2); + expect(fr[0].hello).to.eql("bonjour"); + expect(fr[1].goodbye).to.eql("au revoir"); + + let es = kernel.getAllNamed("Intl", "es"); + expect(es.length).to.eql(2); + expect(es[0].hello).to.eql("hola"); + expect(es[1].goodbye).to.eql("adios"); + + }); + + it("Should be able to resolve tagged multi-injection", () => { + + let kernel = new Kernel(); + + interface Intl { + hello?: string; + goodbye?: string; + } + + kernel.bind("Intl").toConstantValue({ hello: "bonjour" }).whenTargetTagged("lang", "fr"); + kernel.bind("Intl").toConstantValue({ goodbye: "au revoir" }).whenTargetTagged("lang", "fr"); + + kernel.bind("Intl").toConstantValue({ hello: "hola" }).whenTargetTagged("lang", "es"); + kernel.bind("Intl").toConstantValue({ goodbye: "adios" }).whenTargetTagged("lang", "es"); + + let fr = kernel.getAllTagged("Intl", "lang", "fr"); + expect(fr.length).to.eql(2); + expect(fr[0].hello).to.eql("bonjour"); + expect(fr[1].goodbye).to.eql("au revoir"); + + let es = kernel.getAllTagged("Intl", "lang", "es"); + expect(es.length).to.eql(2); + expect(es[0].hello).to.eql("hola"); + expect(es[1].goodbye).to.eql("adios"); + + }); + }); diff --git a/wiki/get_all_named_tagged.md b/wiki/get_all_named_tagged.md index a124319b..57ef8075 100644 --- a/wiki/get_all_named_tagged.md +++ b/wiki/get_all_named_tagged.md @@ -1,15 +1,7 @@ # The Kernel API -The InversifyJS kernel provides some helpers to resolve multi-injections. - -## Kernel.getAll() -```ts -let kernel = new Kernel(); -kernel.bind("Weapon").to(Katana); -kernel.bind("Weapon").to(Shuriken); - -let weapons = kernel.getAll("Weapon"); // returns Weapon[] -``` +The InversifyJS kernel provides some helpers to resolve multi-injections +and ambiguous bindings. ## Kernel.getNamed() Named bindings: @@ -35,6 +27,73 @@ let katana = kernel.getTagged("Weapon", "faction", "samurai"); let shuriken = kernel.getTagged("Weapon", "faction", "ninja"); ``` +## Kernel.getAll() +Get all available bindings for a given identifier: +```ts +let kernel = new Kernel(); +kernel.bind("Weapon").to(Katana); +kernel.bind("Weapon").to(Shuriken); + +let weapons = kernel.getAll("Weapon"); // returns Weapon[] +``` + +## Kernel.getAllNamed() +Get all available bindings for a given identifier that match the given +named constraint: +```ts +let kernel = new Kernel(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +kernel.bind("Intl").toConstantValue({ hello: "bonjour" }).whenTargetNamed("fr"); +kernel.bind("Intl").toConstantValue({ goodbye: "au revoir" }).whenTargetNamed("fr"); + +kernel.bind("Intl").toConstantValue({ hello: "hola" }).whenTargetNamed("es"); +kernel.bind("Intl").toConstantValue({ goodbye: "adios" }).whenTargetNamed("es"); + +let fr = kernel.getAllNamed("Intl", "fr"); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql("bonjour"); +expect(fr[1].goodbye).to.eql("au revoir"); + +let es = kernel.getAllNamed("Intl", "es"); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql("hola"); +expect(es[1].goodbye).to.eql("adios"); +``` + + +## Kernel.getAllTagged() +Get all available bindings for a given identifier that match the given +named constraint: +```ts +let kernel = new Kernel(); + +interface Intl { + hello?: string; + goodbye?: string; +} + +kernel.bind("Intl").toConstantValue({ hello: "bonjour" }).whenTargetTagged("lang", "fr"); +kernel.bind("Intl").toConstantValue({ goodbye: "au revoir" }).whenTargetTagged("lang", "fr"); + +kernel.bind("Intl").toConstantValue({ hello: "hola" }).whenTargetTagged("lang", "es"); +kernel.bind("Intl").toConstantValue({ goodbye: "adios" }).whenTargetTagged("lang", "es"); + +let fr = kernel.getAllTagged("Intl", "lang", "fr"); +expect(fr.length).to.eql(2); +expect(fr[0].hello).to.eql("bonjour"); +expect(fr[1].goodbye).to.eql("au revoir"); + +let es = kernel.getAllTagged("Intl", "lang", "es"); +expect(es.length).to.eql(2); +expect(es[0].hello).to.eql("hola"); +expect(es[1].goodbye).to.eql("adios"); +``` + ## Kernel.isBound() You can use the `isBound` method to check if there are registered bindings for a given service identifier. ```ts