typescript-ioc icon indicating copy to clipboard operation
typescript-ioc copied to clipboard

Multi-injection support

Open julianosam opened this issue 6 years ago • 5 comments

Hey guys! I am heavily using this library in one of my projects, and just ran into a good use case for multi-injection. More specifically, I want to to something like (pseudo code):

  // Provide the implementations, holding them all inside the container
  Container.bind(MyAbstractClass).add(MyConcreteClass1);
  Container.bind(MyAbstractClass).add(MyConcreteClass2);

   // Inject all registered implementations
   constructor(
      @MultiInject private _allImplementations: MyAbstractClass[]
  ) { }
  1. Just to make sure, is there some way to achieve this today that I am missing?
  2. If not, do you guys think it would be a good feature to add?

Let me know your thoughts!

julianosam avatar Mar 30 '18 21:03 julianosam

Hi @julianosam ,

It is not possible with the current version, but I like the idea. We can think something to next release

thiagobustamante avatar Apr 02 '18 13:04 thiagobustamante

I had the same requirement and found a workaround:

// components/base.ts
export abstract class BaseClass {
}
// components/impl1.ts
import { Provides } from "typescript-ioc";
import { BaseClass } from "./base";

@Provides(BaseClass)
export class ImplClass1 extends BaseClass {
}
// components/impl2.ts
import { Provides } from "typescript-ioc";
import { BaseClass } from "./base";

@Provides(BaseClass)
export class ImplClass2 extends BaseClass {
}
// components/index.ts
import { Container } from "typescript-ioc";
import { BaseClass } from "./base";
import { ImplClass1 } from "./impl1";
import { ImplClass2 } from "./impl2";

// this is where the magic happens
export class ImplCollection extends Array<BaseClass> {
  constructor() {
    super();
    this.push(Container.get(ImplClass1) as BaseClass);
    this.push(Container.get(ImplClass2) as BaseClass);
  }
}
// main.ts
import { AutoWired, Inject } from "typescript-ioc";
import { ImplCollection } from "./components/index";

@AutoWired
class Consumer {
  @Inject
  private implementations: ImplCollection;
}

let consumer = new Consumer();

doronguttman avatar Sep 12 '18 20:09 doronguttman

Any updates on this? While the given workaround will achieve the required behavior I think it should work out of the box for a dependency injection container. I have yet to work with an ioc container that doesn't support this feature. This usually comes with a "named" injection - i.e something like the following:

@Name('A')
@Provies(BaseClass)
export class A extend BaseClass { ... }

Then you can do something like
export class B {
    @inject('A') 
    public _myBaseBlassWhichIsA: BaseClass;
}

Below is an example (described in a test) of the unity container behavior with names and multiple implementations: http://www.tomdupont.net/2014/02/understanding-unity-named-registration.html

HarelM avatar Aug 04 '19 06:08 HarelM

any intentions to implement this?

nemcikjan avatar Mar 11 '20 07:03 nemcikjan

Aw, just ran into this.

dustinlacewell avatar Jan 10 '21 20:01 dustinlacewell