在Angular中进行控制反转(IoC)

时间:2017-05-16 08:50:43

标签: angular typescript design-patterns inversion-of-control

考虑我们有一个名为boolean isVisible () 的接口,以及两个实现:MapServiceGoogleMapsService。我想要一个包(或Angular2?)来调用所需的实现,而不是开发人员。

LeafletMapService

这意味着,在组件中我希望服务的类型是接口(因此不依赖于实现):

export interface MapService {
//define my API
}

@Injectable()
export class GoogleMapsService implements MapService {
//implement the API
}

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:5)

所以基于@ jb-nizet的好评;我已经设法使用InjectionToken做了我想做的事情。这是一段代码片段:

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
}

组件:

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) { 
  }
}

答案 1 :(得分:0)

另一种解决方案是使用抽象类而不是接口。

  export abstract class MapService{
   // ...
  }

使您的服务实现此抽象类 并提供

import { Component } from '@angular/core';
import { MapService } from './map.service';
import { GoogleMapsService } from './google-maps.service'; 

@Component({
    template : `...`,
    providers: [
      { provide: MapService, useClass: GoogleMapsService }
    ]
})

export class MyComponent  {

  constructor(private googleMapsService : MapService) {
  }
}

答案 2 :(得分:-1)

在providers数组中使用以下语法:

import { Component } from '@angular/core';
import { MapService } from './map.service';
import { GoogleMapsService } from './google-maps.service'; 

@Component({
    template : `...`,
    providers: [
      { provide: MapService, useClass: GoogleMapsService }
    ]
})

export class MyComponent  {

  constructor(private googleMapsService : MapService) {
  }
}

请注意,您可以在模块范围内执行相同的操作。