Inversifyjs: Referring to one binding with multiple identifiers?

Created on 8 Jun 2016  路  3Comments  路  Source: inversify/InversifyJS

I'm working on refactoring inversify-express-utils and I've come across a case where it would be nice to be able to reference one binding with two different identifiers. In my particular case, I need one identifier to be ambiguous so that I can use getAll(), and then one for an individual binding.

For example:

let controllers: IController[] = this.kernel.getAll<IController[]>("IController");
// sometime later...
let instance: FooController = this.kernel.get<FooController>("FooController");

The only way I've been able to do this is to bind twice.

let kernel = new Kernel();

kernel.bind<IController>("IController").to(FooController);
kernel.bind<FooController>("FooController").to(FooController):

Is this bad practice? If so, is there another way to do this?

question

Most helpful comment

Hi @codyjs sorry for the late reply I was on holidays...

What you have done is fine but there are other ways to do this using metadata.

kernel.bind<IController>("IController").to(FooController).whenTargetNamed("foo");
kernel.bind<IController>("IController").to(BarController).whenTargetNamed("bar");

@injectable()
class SomeClass {
    constructor(@multiInject("IController") ) {
       this._controllers = controllers;
    }
}

class AnpotherClass {
    constructor(
        @inject("IController") @named("foo") fooController,
        @inject("IController") @named("bar") barController
     ) {
       this._fooCntroller= fooController;
       this._barCntroller= fooController
    }
}

Using metadata is probably better because you the interface identifier IController not the class identifier FooController and depending upon an abstraction is better then deepening upon a concretion,

Please close this issue if you don't need more help :)

All 3 comments

Hi @codyjs sorry for the late reply I was on holidays...

What you have done is fine but there are other ways to do this using metadata.

kernel.bind<IController>("IController").to(FooController).whenTargetNamed("foo");
kernel.bind<IController>("IController").to(BarController).whenTargetNamed("bar");

@injectable()
class SomeClass {
    constructor(@multiInject("IController") ) {
       this._controllers = controllers;
    }
}

class AnpotherClass {
    constructor(
        @inject("IController") @named("foo") fooController,
        @inject("IController") @named("bar") barController
     ) {
       this._fooCntroller= fooController;
       this._barCntroller= fooController
    }
}

Using metadata is probably better because you the interface identifier IController not the class identifier FooController and depending upon an abstraction is better then deepening upon a concretion,

Please close this issue if you don't need more help :)

This answers my question. Thanks!

Has something changed here?
I am getting an error when using @multiinjection as suggested by @remojansen above:

No matching bindings found for serviceIdentifier: DiagramChangeListener
Registered bindings:
NodeValidityUpdateOnInitialLayoutListener - named: NodeValidityUpdateOnInitialLayoutListener
ViewportBoundsChangedListener - named: ViewportBoundsChangedListener

Seems like when trying to find the relevant bindings inversify.js filters both bindings as their name doesn't match...?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

remojansen picture remojansen  路  4Comments

AlexanderKiriluyk picture AlexanderKiriluyk  路  4Comments

atrauzzi picture atrauzzi  路  4Comments

RastriginSergey picture RastriginSergey  路  3Comments

asykes74 picture asykes74  路  4Comments