Consider we have an interface called MapService
, and two implementations: GoogleMapsService
and LeafletMapService
. I want a package (or Angular2?) to call the needed implementation rather than developers.
export interface MapService {
//define my API
}
@Injectable()
export class GoogleMapsService implements MapService {
//implement the API
}
That means, in the component I want the type of the service to be the interface (so not depending on the implementation):
import { Component } from '@angular/core';
import { MapService } from './map.service';
import { GoogleMapsService } from './google-maps.service';
@Component({
template : `...`,
providers: [GoogleMapsService]
})
export class MyComponent {
constructor(private googleMapsService : MapService) { //notice the type of the service here
}
}
How can I achieve that?
So based on @jb-nizet's great comment; I've managed to do what I want using InjectionToken. Here is a code snippets:
import { Injectable, InjectionToken } from '@angular/core';
export const GOOGLE_MAPS_IMPL = new InjectionToken<MapService>('googleMapImpl');
export interface MapService {
//define the API
}
@Injectable()
export class GoogleMapsService implements MapService {
//implement the API
}
And the component:
import { Component, Inject } from '@angular/core';
import { MapService } from './map.service';
import { GoogleMapsService, GOOGLE_MAPS_IMPL } from './google-maps.service';
@Component({
template : `...`,
providers: [{ provide: GOOGLE_MAPS_IMPL, useClass: GoogleMapsService }]
})
export class MyComponent {
constructor(@Inject(GOOGLE_MAPS_IMPL) private googleMapsService : MapService) {
}
}