Injecting all classes that implement a certain interface using TSyringe

Is it possible for TSyringe to inject all classes that implement a specific interface or extend an abstract class? For example:

@injectable()
export interface IService {
    foo(): void;
}

@injectable()
export class Service1 implements IService {
    foo() { console.out("bar"); }
}

@injectable()
export class Service2 implements IService {
    foo() { console.out("baz"); }
}

export class CollectorService {
    constructor(
        @inject('Service')
        services: IService[]
    ) {
        services.forEach(s => s.foo());
    }
}

I recently started using TSyringe and I'm not sure how to register this kind of dependency in the DI container. I'd like to achieve something similar to Spring's @Autowire annotation.

Answer №1

I had trouble implementing the registry per class according to Aníbal Deboni Neto's answer on Stack Overflow. Instead, I found success using a proxy class to consolidate all the registries. Incorporating a Symbol eliminated the need for any magic strings in my code.

interface IBar {}

@injectable()
class Foo implements IBar {}
@injectable()
class Baz implements IBar {}

@registry([
  {token: Bar.token, useToken: Foo},
  {token: Bar.token, useToken: Baz}
])
abstract class Bar {
  static readonly token = Symbol("IBar");
}

@injectable()
class User{
  constructor(@injectAll(Bar.token) private bars: IBar[]) {
  }
}

const bars: IBar[] = container.resolveAll<IBar>(Bar.token);
const user: User = container.resolve(User);

Source: GitHub - microsoft/tsyringe

Answer №2

My approach may not be perfect, but I was able to achieve multiple injection by using the following code:

import {
  injectable, injectAll, registry, container,
} from 'tsyringe';

interface ValueClass {
  value: string;

  sayMyValue(): void;
}

@injectable()
@registry([{ token: 'ValueClass', useClass: ValueClass1 }])
class ValueClass1 implements ValueClass {
  sayMyValue(): void {
    console.log('ValueClass1');
  }

  value: string = 'value1';
}

@injectable()
@registry([{ token: 'ValueClass', useClass: ValueClass2 }])
class ValueClass2 implements ValueClass {
  value: string;

  sayMyValue(): void {
    console.log('ValueClass2');
  }
}

@injectable()
export class AppClass {
  constructor(
    @injectAll('ValueClass')
    private valueClasses: ValueClass[],
  ) { }

  run() {
    this.valueClasses
      .forEach((valueClass: ValueClass) => { valueClass.sayMyValue(); });
  }
}

const v = container.resolve(AppClass);
v.run();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Jest encountered an error while trying to run the test suite: No message was given

Currently, I am in the process of converting my existing tests to utilize TypeScript with ts-jest. Although I have managed to locate all the necessary files, every single test is failing and producing the following error: FAIL src/components/Buttons/__t ...

I'm looking to locate the API documentation for AngularJS TypeScript

After transitioning from using AngularJS 1.4 and plain JavaScript to now working with AngularJS 1.5 but utilizing TypeScript, I have found it challenging to find helpful documentation. For instance, when trying to inject services like $q or $timeout into m ...

Encountering issues in d3.js following the transition to Angular 8

After upgrading my Angular 4 app to Angular 8, I encountered an issue where the application works fine in development build but breaks in production build. Upon loading the application, the following error is displayed. Uncaught TypeError: Cannot read p ...

The server response value is not appearing in Angular 5

It appears that my client is unable to capture the response data from the server and display it. Below is the code for my component: export class MyComponent implements OnInit { data: string; constructor(private myService: MyService) {} ngOnInit ...

Steps for sorting items from a list within the past 12 hours

I'm currently working with Angular and I have data in JSON format. My goal is to filter out items from the last 12 hours based on the "LastSeen" field of the data starting from the current date and time. This is a snippet of my data: { "Prod ...

Discord.js experiences limitations with storing multiple data in conjunction with TypeScript when using MySQL

Question Currently, I am developing a Discord bot to track messages using typescript and discord.js. I have included my code below. The issue I am facing is that the data is not being saved correctly. Each time a user sends messages, their message count i ...

Utilizing the variables defined in the create function within the update function of Phaser 3

I'm facing an issue in my game where I can't access a variable that I declared in the create function when trying to use it in the update function. Here is a snippet of what I'm trying to achieve: create() { const map = this.make. ...

Angular correctly displaying specific array items within button elements

I am facing an issue with my dashboard where I have 4 items in an array and 4 buttons on display. My goal is to assign each item with a specific button, but currently, it shows 4 buttons for each "hero" resulting in a total of 16 buttons. I have tried usin ...

Having trouble accessing the "emit" property of an undefined element within the navLinks FullCalendar component in Angular

While incorporating full-calendar from fullcalendar.io into my Angular project, I made sure to install all necessary plugins like dayGrid, timeGrid, and interaction. Utilizing navLinks functionality, I came across this resource -> https://fullcalendar.i ...

Universal categories, limitations, and hereditary traits

As a newcomer to Typescript and generics, I am unsure if I have encountered a bug/limitation of Typescript or if I am missing the correct approach to achieve my desired outcome. I have a base class called Widget which is generic and holds a value of type ...

Issue TS2304: Unable to locate identifier when passing arguments to React Functional Component

Using the following code snippet: import ReactEChartsCore from 'echarts-for-react/lib/core'; // Import the echarts core module, which provides the necessary interfaces for using echarts. import * as echarts from 'echarts/core'; // impor ...

A guide on refreshing the dependencies list within Angular's node modules and package.json files

A close friend sent me the angular src folder, which I used to create a new Angular project. However, when I replaced my newly created src folder with my friend's and tried running the application using npm start, I encountered errors related to missi ...

Assigning a generic object to a Partial type

Recently I've been diving back into TypeScript, but I've hit a roadblock with this particular issue. export class CrossBrowserStorage<T> { getValue<P extends keyof T>( key: P, defaultValue: T[P] ): Observable<T[P]> ...

Retrieving data from a child node using Jsonpath

Displayed below is a sample of JSON input data: { "India":{ "Attributes":{"Time":"2006-05-04T03:22:11.499Z"}, "ActiveCity":{ "profile":"Mumbai" }, "CurrentCities":{ "Mumbai":{"population":"121212121","Are ...

An issue occurred when clicking on a line due to the filter

Issue at Hand: Currently, I am facing a problem where selecting an item from the list by clicking on the button leads me to access the information of a different item when the filter is applied. Desired Outcome: I wish to be able to access the correct inf ...

Is there a way to verify if a user taps outside a component in react-native?

I have implemented a custom select feature, but I am facing an issue with closing it when clicking outside the select or options. The "button" is essentially a TouchableOpacity, and upon clicking on it, the list of options appears. Currently, I can only cl ...

There is an issue with the Next.js middleware: [Error: The edge runtime is not compatible with the Node.js 'crypto' module]

Struggling with a problem in next.js and typescript for the past 4 days. If anyone can provide some insight or help with a solution, it would be greatly appreciated. Thank you! -- This is my middleware.ts import jwt from "jsonwebtoken"; import { ...

Utilizing an Angular framework to access external JavaScript libraries when the document is fully

I'm incorporating a third-party JavaScript library into my .NET Core ASP Angular application. This library executes its functionality within the $(document).ready method. However, I've encountered an issue where the library's logic isn' ...

What are the consequences of relying too heavily on deep type inference in React and Typescript?

In the process of migrating my React + Javascript project to Typescript, I am faced with preserving a nice unidirectional flow in my existing code. The current flow is structured as follows: 1. Component: FoobarListComponent -> useQueryFetchFoobars() 2 ...

Testing components in React involves creating or invoking specific construct or call signatures

Exploring this React component: import { Meta } from '@storybook/react'; export function MyComponentExample() { return ( <div>my component example</div> ); } export default { component: MyComponentExample, title: 'M ...