Inversifyjs: Feature request: container.rebind()

Created on 31 Jan 2017  路  6Comments  路  Source: inversify/InversifyJS

Hi,
I'm just wondering what is the best solution for registering components that follows the decorator pattern in order to achieve composition.

Currently in our libraries we have a main module that exposes services whom can be overridden in a submodule multiple times, something like this:

container.unbind("IHttpClient");
container.bind<IHttpClient>("HttpClient").to(HttpClient).inSingletonScope().whenInjectedInto(AuthHttpClient);
container.bind<IHttpClient>("IHttpClient").to(AuthHttpClient).inSingletonScope();

Can this registration be simplified for future overwrites? Cause if I want to add another decorator to my service all the previous lines will be duplicated plus the new service registered.

Most helpful comment

This is now available in 3.1.0

All 6 comments

+1 on an easier way to overwrite bindings.
If you're swapping out dependencies for testing it becomes very verbal very quickly

Hi guys, let me see if I understand the issue correctly. At the moment you write:

container.unbind("IHttpClient");

container.bind<IHttpClient>("HttpClient")
    .to(HttpClient)
    .inSingletonScope()
    .whenInjectedInto(AuthHttpClient);

container.bind<IHttpClient>("IHttpClient")
    .to(AuthHttpClient)
    .inSingletonScope();

But you only want to override the IHttpClient binding:

container.bind<IHttpClient>("IHttpClient")
    .to(AuthHttpClient)
    .inSingletonScope()

Is that correct?

Yes, but also with the ability to override the dependencies passed to the base service.
You can have a look at this where you can find a Java example regarding the construction of the instances (Window is the HttpClient of the previous code):

Window decoratedWindow = new HorizontalScrollBarDecorator (
                new VerticalScrollBarDecorator (new SimpleWindow()));

I was thinking about an elegant solution to do this in inversify with the ability to override bindings in kernel modules.

I'm considering adding a new Container method named rebind:

container.rebind<IHttpClient>("IHttpClient")
    .to(AuthHttpClient)
    .inSingletonScope();

It could also be used from a module:

let someModule = new ContainerModule((bind, unbind, rebind) => {
    rebind<IHttpClient>("IHttpClient")
        .to(AuthHttpClient)
        .inSingletonScope();
});

container.load(someModule);

The only limitation is that if multiple bindings are available for one service identifier (e.g. "IHttpClient") they will be all removed and replace by one single binding. So rebind will not support contextual constraints and multi injections.

Maybe in future improvements, rebind will support named and tagged constraints. But we need to implement this first.

Rebind is definitely an improvement. Looking forward to have rebind support for tagged constraints in order to cover all of ours use cases.
Thanks for your incredible work and time.

This is now available in 3.1.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jshearer picture jshearer  路  4Comments

remojansen picture remojansen  路  4Comments

RastriginSergey picture RastriginSergey  路  3Comments

stjepangolemac picture stjepangolemac  路  5Comments

pmoleri picture pmoleri  路  5Comments