Angular 2可注射接口?

时间:2017-02-23 17:32:06

标签: angular typescript dependency-injection interface inversion-of-control

今天我偶然发现了一些我认为不会给我带来麻烦的事情。

在Java和Spring中,我可以声明两个bean都实现一个给定的接口,而在另一个注入它们的类中我只使用接口;这实际上就是我对IoC的喜爱:你不必知道你正在使用什么对象,只有它善良

所以在我的小Angular2 / Typescript程序中,我试图做同样的事情:

webapp.module.ts:

... 
import { WebAppConfigurationService } from './app/services/webapp.configuration.service';

@NgModule({
  ...
  providers: [WebAppConfigurationService]
})
export class AppModule { }

tnsapp.module.ts:

...
import { TnsConfigurationService } from './services/tns.configuration.service';

@NgModule({
   ...
   providers: [TnsConfigurationService]
})
export class AppModule { }

这两个模块都使用不同的提供商:TnsConfigurationServiceWebAppConfigurationService

但是,这两个@Injectable服务实现了相同的接口:

configuration.interface:

export interface IConfigurationService {
    ...
}

最后,在我的一个组件中,我使用了我在开始时向您展示的其中一个模块提供的注射剂:

import { IConfigurationService } from './configuration.interface';

export class HeroesService {

    constructor(private configurationService: IConfigurationService) { }
}

我的期望是最后一个组件注入了正确的服务,即使参数只是明确定义了接口。当然我收到一个错误("错误:无法解决HeroesService&#34的所有参数;)

现在,我不希望有一个简单的解决方案,因为它听起来像一个建筑缺乏。但也许有人可以指出我的替代设计?

1 个答案:

答案 0 :(得分:8)

为了注册提供者,应将其注册为提供者。没有IConfigurationService提供商。它不能是提供者,因为接口不会存在于已编译的JS代码中。

应该用作提供者令牌的接口的常见做法是抽象类:

abstract class ConfigurationService { ... }

@Injectable()
class WebAppConfigurationService extends ConfigurationService { ... }

...
providers: [{ provide: ConfigurationService, useClass: WebAppConfigurationService }]
...

此配方通常由Angular 2本身使用,例如http://apps.timwhitlock.info/unicode/inspect?s=%EF%BB%BF%EF%BB%BFabstract NgLocalization class