Let's imagine the following class hierarchy:
interface Weapon {
}
interface BladedWeapon extends Weapon {
}
class Katana implements BladedWeapon {
}
class Stick implements Weapon {
}
Current bindings are following:
container.bind<Weapon>('Weapon').to(Stick).whenTargetNamed('stick');
container.bind<Weapon>('Weapon').to(Katana).whenTargetNamed('katana');
In one part of my code I would like to get all instaces of Weapon
interface:
@multiInject('Weapon') weapons: Weapon[];
In the other part I would like to get katana:
@inject('Weapon') @named('katana') katana: Katana;
The problem is InversifyJS cannot perform multi-injection due to named bindings:
Error: No matching bindings found for serviceIdentifier: 'Weapon'
How to solve this issue?
P.S. I use InversifyJS 6.0.1
For now I found not clean, but working way to solve the issue:
container.bind<Weapon>('Weapon').to(Stick);
container.bind<Weapon>('Weapon').to(Katana);
container.bind<Katana>('Katana').toDynamicValue(context => {
const weapons = context.container.getAll<Weapon>('Weapon');
for (const weapon of weapons) {
if (isKatana(weapon)) {
return weapon;
}
}
throw new Error('Katana is not found in DI container');
}).whenTargetNamed('katana');
In the code above I don't use names while defining bindings that could be injected using multi-injection. For specific weapon I create dynamic named binding and just search required dependency among registered.