5

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?)

1 Answer 1

11

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot, worked like a charm! For a working example see frostnova.ch/angular2 (code: github.com/pwalser75/angular2-demo/blob/master/src/app/services/…)
This is basically how I'd do it. My only quibble is how you inject it. I'd inject the token rather than the injector. constructor(@Inject(SearchStrategyToken) searchStrategies: SearchStrategy[]) {...}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.