Angular 2 可注入接口?
Angular 2 Injectable Interface?
今天我偶然发现了一些我认为不会给我带来麻烦的事情。
在 Java 和 Spring 中,我可以声明两个都实现给定接口的 bean,而在注入它们的另一个 class 中,我只使用接口;事实上,这就是我喜欢 IoC 的地方:你真的不需要知道你正在使用的是什么对象,只要它是 kind.
所以在我的 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 { }
这两个模块都使用不同的提供商:TnsConfigurationService
或 WebAppConfigurationService
。
但是,这两个 @Injectable
服务实现相同的接口:
configuration.interface:
export interface IConfigurationService {
...
}
最后,在我的一个组件中,我使用了我在开头向您展示的这些模块之一提供的可注射物:
import { IConfigurationService } from './configuration.interface';
export class HeroesService {
constructor(private configurationService: IConfigurationService) { }
}
我的期望是最后一个组件被注入正确的服务,即使参数只是明确定义接口。当然我得到一个错误 ("Error: Can't resolve all parameters for HeroesService")
现在,我不希望有一个简单的解决方案,因为这听起来像是架构上的缺陷。但也许有人可以向我指出另一种设计?
为了注入提供者,应该将其注册为提供者。没有 IConfigurationService
提供商。而且它不能是提供者,因为编译后的 JS 代码中不存在接口。
应该用作提供者令牌的接口的常见做法是抽象的 类:
abstract class ConfigurationService { ... }
@Injectable()
class WebAppConfigurationService extends ConfigurationService { ... }
...
providers: [{ provide: ConfigurationService, useClass: WebAppConfigurationService }]
...
这个食谱通常被Angular 2 自己使用,例如abstract NgLocalization
class and concrete NgLocaleLocalization
implementation.
今天我偶然发现了一些我认为不会给我带来麻烦的事情。
在 Java 和 Spring 中,我可以声明两个都实现给定接口的 bean,而在注入它们的另一个 class 中,我只使用接口;事实上,这就是我喜欢 IoC 的地方:你真的不需要知道你正在使用的是什么对象,只要它是 kind.
所以在我的 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 { }
这两个模块都使用不同的提供商:TnsConfigurationService
或 WebAppConfigurationService
。
但是,这两个 @Injectable
服务实现相同的接口:
configuration.interface:
export interface IConfigurationService {
...
}
最后,在我的一个组件中,我使用了我在开头向您展示的这些模块之一提供的可注射物:
import { IConfigurationService } from './configuration.interface';
export class HeroesService {
constructor(private configurationService: IConfigurationService) { }
}
我的期望是最后一个组件被注入正确的服务,即使参数只是明确定义接口。当然我得到一个错误 ("Error: Can't resolve all parameters for HeroesService")
现在,我不希望有一个简单的解决方案,因为这听起来像是架构上的缺陷。但也许有人可以向我指出另一种设计?
为了注入提供者,应该将其注册为提供者。没有 IConfigurationService
提供商。而且它不能是提供者,因为编译后的 JS 代码中不存在接口。
应该用作提供者令牌的接口的常见做法是抽象的 类:
abstract class ConfigurationService { ... }
@Injectable()
class WebAppConfigurationService extends ConfigurationService { ... }
...
providers: [{ provide: ConfigurationService, useClass: WebAppConfigurationService }]
...
这个食谱通常被Angular 2 自己使用,例如abstract NgLocalization
class and concrete NgLocaleLocalization
implementation.