InversifyJS icon indicating copy to clipboard operation
InversifyJS copied to clipboard

@Provide multi-inject support

Open dustinlacewell opened this issue 5 years ago • 4 comments

It seems that there is no way to properly use @provide with multi-injection. It seems related to this issue:

https://github.com/inversify/InversifyJS/issues/1238

Expected Behavior

Multiple classes decorated with @provide(Command) should be properly injected as a Command[] when doing @multiInject("Command") commands: Command[]

Current Behavior

Error: No matching bindings found for serviceIdentifier: Command

dustinlacewell avatar Jan 10 '21 20:01 dustinlacewell

Is there any good solution to this issue yet?

fabian-st avatar Apr 03 '21 11:04 fabian-st

Hi guys, I'll try to recreate it as soon as I can.

notaphplover avatar Apr 17 '21 10:04 notaphplover

@dustinlacewell, @fabian-st I'm unable to recreate the bug. Can you provide a minimal example? I wrote a test for this issue but it passes in the inversify-binding-decorator project without modifying a single line of code:

import "reflect-metadata";

import { expect } from "chai";
import { Container, multiInject } from "inversify";
import { buildProviderModule } from "../../src";
import provide from "../../src/decorator/provide";

// https://github.com/inversify/InversifyJS/issues/1280
describe("Issue 1280", () => {
    it("Should be able get all the services injected", () => {

        const container = new Container();
        const weaponIdentifier = "someWeaponIdentifier";
        const ninjaIdentifier = "someNinjaIdentifier";

        interface Weapon {
            hit(): void;
        }

        @provide(weaponIdentifier, true)
        class Katana implements Weapon {
            public hit() {
                return "cut!";
            }
        }

        @provide(weaponIdentifier, true)
        class BetterKatana implements Weapon {
            public hit() {
                return "cut better!";
            }
        }

        @provide(ninjaIdentifier, true)
        class Ninja {
            constructor(
                @multiInject(weaponIdentifier) public readonly weapons: Weapon[],
            ) {}
        }

        container.load(buildProviderModule());

        const containerWeapons = container.getAll<Weapon>(weaponIdentifier) as Weapon[] & [Weapon, Weapon];

        const ninja = container.get<Ninja>(ninjaIdentifier);

        const ninjaWeapons = ninja.weapons as Weapon[] & [Weapon, Weapon];

        expect(containerWeapons.length).to.eq(2);
        expect(containerWeapons[0] instanceof BetterKatana).eql(true);
        expect(containerWeapons[1] instanceof Katana).eql(true);

        expect(ninja instanceof Ninja).eql(true);

        expect(ninjaWeapons.length).to.eq(2);
        expect(ninjaWeapons[0] instanceof BetterKatana).eql(true);
        expect(ninjaWeapons[1] instanceof Katana).eql(true);
    });
});

Maybe I'm missing something :thinking:

notaphplover avatar Apr 17 '21 12:04 notaphplover

@notaphplover
multiInject with fluentProvide is not working?

import 'reflect-metadata';
import { Container, multiInject } from 'inversify';
import { buildProviderModule, provide, fluentProvide } from 'inversify-binding-decorators';


@fluentProvide('X').whenTargetNamed('1')
  .done()
class A {
  public name = 'a';
}


@fluentProvide('X').whenTargetNamed('2')
  .done()
class B {
  public name = 'b';
}


@provide('Z')
class D {
  public name = 'D';
}


@provide('Z')
class E {
  public name = 'e';
}


@provide('Entity')
class Entity {
  public constructor(@multiInject('Z') public entities: any[]) {
    console.log(entities);
  }
}

@provide('Controller')
class Controller {
  public constructor(@multiInject('X') public entities: any[]) {
    console.log(entities);
  }
}

const container = new Container();
container.load(buildProviderModule());
console.log('getAll X', container.getAll('X'));
console.log('provide Z', container.getAll('Entity'));
console.log('fluentProvide X', container.getAll('Controller')); // will throw :


Error: No matching bindings found for serviceIdentifier: X
Registered bindings:
 B - named: 2 
 A - named: 1 
image

etoah avatar Mar 23 '22 14:03 etoah