Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-injection support #28

Open
julianosam opened this issue Mar 30, 2018 · 5 comments
Open

Multi-injection support #28

julianosam opened this issue Mar 30, 2018 · 5 comments

Comments

@julianosam
Copy link

julianosam commented Mar 30, 2018

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!

@thiagobustamante
Copy link
Owner

Hi @julianosam ,

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

@doronguttman
Copy link

doronguttman commented Sep 12, 2018

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();

@HarelM
Copy link

HarelM commented Aug 4, 2019

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

@nemcikjan
Copy link

any intentions to implement this?

@dustinlacewell
Copy link

Aw, just ran into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants