Injecting classes from files not yet imported with tsyringe

98 views Asked by At

I want to inject several different instances all having the same token with tsyringe. The constraint I have is that every class is in its own file, and I want them to self register in the DI container. Ex:

fruit.ts

export default interface Fruit {
}

apple.ts

import {registry, singleton} from "tsyringe";
import Fruit from "./fruit"

@singleton
@registry([{token: "Fruit", useClass: Apple}])
export default class Apple implements Fruit {
}

banana.ts

import {registry, singleton} from "tsyringe";
import Fruit from "./fruit"

@singleton
@registry([{token: "Fruit", useClass: Banana}])
export default class Banana implements Fruit {
}

fruit.processor.ts

import {injectAll, singleton} from "tsyringe";
import Fruit from "./fruit";

@singleton()
export default class FruitProcessor {
  constructor(@injectAll("Fruit") private fruits: Fruit[]) {
  }
}

index.ts

import "reflect-metadata";
import {container} from "tsyringe";
import FruitProcessor from "./fruit.processor";

container.resolve(FruitProcessor);

What I did expect from this was all the fruits to be added to the container and then injected into FruitProcessor's constructor, but all I get is an error saying:

Cannot inject the dependency "fruits" at position #0 of "FruitProcessor" constructor. Reason: Attempted to resolve unregistered dependency token: "Fruit"

Doing some experiments, I can see that this would work if I change it to one of these two options:

  1. Adding an import to the fruit classes before injecting FruitProcessor:
import "./banana";
import "./apple";
container.resolve(FruitProcessor);
  1. Moving the registry to a separate file:
import {registry} from "tsyringe";

@registry([
  {token: "Fruit", useClass: Apple},
  {token: "Fruit", useClass: Banana}
])
class Registry {
}

None of these options make me happy, since they are prone to errors and mistakes. Is there a way to do this in an automated way, without needing imports nor a separate Registry?

0

There are 0 answers