InversifyJS icon indicating copy to clipboard operation
InversifyJS copied to clipboard

How to unbind & rebind named/tagged?

Open geekox86 opened this issue 3 years ago • 6 comments

Greetings and thank you for the wonderful library. Great job!

Is there a way to unbind and rebind specific named/tagged bindings?

geekox86 avatar Jul 08 '21 06:07 geekox86

Same! Is that thing?

wi-ski avatar Jan 15 '22 01:01 wi-ski

Any progress?

aztack avatar Feb 03 '23 07:02 aztack

it was 2023... no reaction

safiullin-at avatar Jul 06 '23 11:07 safiullin-at

This might not solve your problem 100%, but here is a method I have added to my container.ts file that lets me unbindTagged:

container.ts

import { Container } from "inversify"

export type Newable<T> = new (...args: any[]) => T;
export interface Abstract<T> {
    prototype: T;
}
export type ServiceIdentifier<T = unknown> = (string | symbol | Newable<T> | Abstract<T>);
declare module 'inversify' {
  interface Container {
    unbindTagged: <T>(serviceIdentifier: ServiceIdentifier<T>, key: string, value: string) => void
  }
}

const container = new Container()

container.unbindTagged = <T>(serviceIdentifier: ServiceIdentifier<T>, key: string, value: string) => {
  let bindings = container['_bindingDictionary'].get(serviceIdentifier)

  for (let binding of bindings) {
    const metadata = binding.constraint.metaData
    if (metadata && metadata.key === key && metadata.value === value) {
      container['_deactivateSingletons'](binding)
      let newBindings = bindings.filter((binding: any) => {
        return !(binding.constraint.metaData.key === key && binding.constraint.metaData.value === value)
      })
      container['_bindingDictionary']['_map'].set(serviceIdentifier, newBindings)
    }
  }
}

index.ts

import { container } from "./container"

class Car {}
class BMW extends Car {}
class Honda extends Car {}

async function main() {
  container.bind(Car).to(BMW).whenTargetTagged('make', 'bmw')
  container.bind(Car).to(Honda).whenTargetTagged('make', 'honda')

  container.unbindTagged(Car, 'make', 'honda')
  let cars = container.getAll(Car)
  console.log(cars)
  // [[class BMW extends Car]]
}

main()

You can then container.bind(Car).to(Honda).whenTargetTagged('make', 'honda') to rebind.

Calling private methods on the container is never recommended, but this library hasn't been published since 2021, and you can lock npm to a specific version.

logikaljay avatar Dec 15 '23 23:12 logikaljay

Sorry for the lack of response here, the project went through an unmaintained period but we have been publishing releases again recently (6.0.2 at the end of October 2023)

--

I think this ability would be a good addition to the library. IMO we should aim to introduce this into an official release, @logikaljay has provided a nice API for it which will suit the main Inversify API well. @PodaruDragos what are your thoughts?

Jameskmonger avatar Dec 17 '23 14:12 Jameskmonger

Added to milestone 6.1.0 pending agreement from other contributors.

Jameskmonger avatar Dec 17 '23 14:12 Jameskmonger