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:
- Adding an import to the fruit classes before injecting FruitProcessor:
import "./banana";
import "./apple";
container.resolve(FruitProcessor);
- 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?