Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 How can I Inject all interface implementation to service as list?

I'm learning Angular2 with Typescript and I have a problem.

I have two classe that imprements same interface. How can I inject them to a service as a list ?

I read about opaquetoken https://angular.io/docs/ts/latest/guide/dependency-injection.html#opaquetoken

But I don't know if I need to use it and how to use it.

export interface CheckerInterface {
    check(text : string) : boolean
}

export class Checker1 implements CheckerInterface {
    check(text : string) : boolean {
    //do something 
    return true;
}

export class Checker2 implements CheckerInterface {
    check(text : string) : boolean {
    //do something 
    return true;
}

@Injectable()
export class Service {

  constructor(private checkers: CheckerInterface[]) {  //??
      checkers.foreach( checker => checker.check(somestring));
  }

}

Thanks for any help !

like image 432
Rafałek Avatar asked Mar 27 '17 14:03

Rafałek


People also ask

How do you inject service into another service?

Use the @Injectable() decorator on any service that depends on another. Inject the other services into the constructor of the dependent service.

How many ways we can inject service in Angular?

There are three types of Dependency Injections in Angular, they are as follows: Constructor injection: Here, it provides the dependencies through a class constructor. Setter injection: The client uses a setter method into which the injector injects the dependency.

Can we inject Service inside service in Angular?

You can inject an Angular service in a component, service, directive etc by specifying the service and its type in a component's constructor. Note that injecting a service through a class constructor is, in general, tree-shakable.

How do you inject service in Angular?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.


1 Answers

You need to either add the array as a provider, or use multi: true in the provider configuration.

export const CHECKERS = new OpaqueToken('one');

@NgModule({
  providers: [
     { provide: CHECKERS, useValue: [new Checker1(), new Checker2()] },
  ]
})

Or

@NgModule({
  providers: [
     { provide: CHECKERS, useClass: Checker1, multi: true },
     { provide: CHECKERS, useClass: Checker2, multi: true },
  ]
})

The second one is probably preferable, as you let Angular create them, allowing them to be injected with their own dependencies if needed.

Then you just need to use the CHECKERS token when you inject

import { Inject } from '@angular/core';
import { CHECKERS } from './wherever';

constructor(@Inject(CHECKERS) private checkers: CheckerInterface[]) { 

UPDATE

As of Angular 4, InjectionToken is used instead of OpaqueToken

export const CHECKERS = new InjectionToken<CheckerInterface>('CheckerInterface');
like image 80
Paul Samsotha Avatar answered Sep 19 '22 08:09

Paul Samsotha