Angular 2 可注入接口?
Posted
技术标签:
【中文标题】Angular 2 可注入接口?【英文标题】:Angular 2 Injectable Interface? 【发布时间】:2017-07-14 08:03:28 【问题描述】:今天我偶然发现了一些我认为不会给我带来麻烦的东西。
在 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
这两个模块都使用不同的提供程序:TnsConfigurationService
或 WebAppConfigurationService
。
但是,这两个@Injectable
服务实现了相同的接口:
配置界面:
export interface IConfigurationService
...
最后,在我的一个组件中,我使用了我在开头向您展示的这些模块之一提供的注射剂:
import IConfigurationService from './configuration.interface';
export class HeroesService
constructor(private configurationService: IConfigurationService)
我的期望是最后一个组件被注入正确的服务,即使参数只是明确定义接口。当然我得到一个错误(“错误:无法解析 HeroesService 的所有参数”)
现在,我不希望有一个简单的解决方案,因为这听起来是架构上的不足。但也许有人可以指出另一种设计?
【问题讨论】:
看看 DI 文档angular.io/docs/ts/latest/guide/… @yurzui 我喜欢它:“这不是 Angular 的错。” :-) 好吧,也许还有一个漂亮的方法来做到这一点......我稍后会读到这个OpaqueToken
OpaqueToken 主要用于非类提供者(工厂和值)。
【参考方案1】:
为了注入提供程序,应将其注册为提供程序。没有IConfigurationService
提供者。而且它不能是提供者,因为编译的JS代码中不存在接口。
应该用作提供者令牌的接口的常见做法是抽象类:
abstract class ConfigurationService ...
@Injectable()
class WebAppConfigurationService extends ConfigurationService ...
...
providers: [ provide: ConfigurationService, useClass: WebAppConfigurationService ]
...
这个配方通常被 Angular 2 本身使用,例如abstract NgLocalization
class 和 concrete NgLocaleLocalization
implementation。
【讨论】:
这看起来很不错,我会在明天早上(UTC)通知你 对于 angular 4 / 5,这仍然是最新的吗?来自其他支持 DI 的语言,例如 Java,我发现必须使用抽象类作为提供者真的很奇怪。 @PhilipFeldmann 是的,仍然完全相关。据我所知,对于有 Java 背景的人来说,TS 及其接口看起来已经够陌生了,所以也就不足为奇了。以上是关于Angular 2 可注入接口?的主要内容,如果未能解决你的问题,请参考以下文章