Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: lookup all providers implementing a specific interface

In my Angular (4+) application, I want to create a basic plugin mechanism:

  • The extension point is defined as an interface
  • Extensions implement that interface
  • To find all extensions, I need to discover the implementations of that interface at runtime.

Example: interface SearchStrategy with implementations PersonSearchStrategy and DocumentSearchStrategy (both services, registered as providers).

Is there a way to dynamically get instances of these services by querying for implementations of the SearchStrategy interface? How?

(might be some Injector related functionality?)

like image 266
Peter Walser Avatar asked Jan 22 '18 13:01

Peter Walser


1 Answers

It's kinda possible, provided if you register the services with InjectionToken and use provide multi.

You can create an injection token with interface.

export const SearchStrategyToken = new InjectionToken<SearchStrategy[]>('SearchStrategy');

In your module register:

providers: [
  {provide: SearchStrategyToken, useClass: PersonSearchStrategy, multi: true}, 
  {provide: SearchStrategyToken, useClass: DocumentSearchStrategy, multi: true},
]

In your component or service:

constructor(private injector: Injector) {

  const services = this.injector
  .get(SearchStrategyToken); // return 2 items [ PersonSearchStrategy, DocumentSearchStrategy ]

  const personSearch = services.find(x => x.constructor.name === 'PersonSearchStrategy');

  const docSearch = services.find(x => x.constructor.name === 'DocumentSearchStrategy');

}

Code example provided here: https://stackblitz.com/edit/angular-clxr6k.

However, it would be good if you provide more details on your use case. Probably there are better solution than going for the above route.

like image 158
Chybie Avatar answered Sep 20 '22 13:09

Chybie