inversify / InversifyJS

A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript.
http://inversify.io/
MIT License
11.34k stars 719 forks source link

What should I do if I want to multiInject multiple targetName? #1300

Closed ytetsuro closed 1 week ago

ytetsuro commented 3 years ago

I want a Ninja per Weapon in every game board class.

@injectable()
class Katana implements Weapon {
    public hit() {
        return "cut!";
    }
}

@injectable()
class Shuriken implements Weapon {
    public hit() {
        return "hit!";
    }
}

@injectable()
class Ninja implements Warrior {
    public constructor(
        @inject(TYPES.Weapon) private readonly weapon: Weapon
    ) {
    }

    public fight() { return this._katana.hit(); }
}

@injectable()
class GameBoard {
    public constructor(
        @multiInject(TYPES.Warrior) private readonly warriors: Warrior[]
    ) {
    }
}

const container = new Container();
container.bind(TYPE.Weapon).to(Shuriken).whenTargetName('shuriken');
container.bind(TYPE.Weapon).to(Katana).whenTargetName('katana');
container.bind(TYPE.Warrior).to(Ninja);
container.bind(GameBoard).to(GameBoard);

// ???

Expected Behavior

I want an instance that is equivalent to the following code.

new GameBoard([
  new Ninjya(new Katana()),
  new Ninjya(new Shuriken()),
]);

Current Behavior

Can't do this currently?

dcavanagh commented 3 years ago

I think the best way to do this would be to use a factory.

ytetsuro commented 3 years ago

@dcavanagh

Thanks for taking the time to reply. I think the only current solution is probably to create a factory. Does inversifyJS want to change to allow multiple target names in multiInjection? Is it worth the PR to make that change?

dcavanagh commented 3 years ago

@ytetsuro we are pretty swamped trying to revive this project. Are you interested in helping out?

Could you describe your proposal some more and we can have a discussion about it.

notaphplover commented 1 week ago

As said, a factory is probably the way to go. Trying to multiInject a service with a single binding should return a single Ninja.