Angular 2 可注入接口? [英] Angular 2 Injectable Interface?

查看:15
本文介绍了Angular 2 可注入接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Today I stumbled upon something that I didn't think would cause me trouble.

在 Java 和 Spring 中,我可以声明两个都实现给定接口的 bean,而在另一个注入它们的类中,我只使用接口;事实上,这就是我喜欢 IoC 的原因:你不需要真正知道你在使用什么对象,只要它种类.

In Java and Spring, I can declare two beans that both implement a given interface, while in another class where they are injected I only work with the interface; this is in fact what I love with IoC: you don't really have to know what object you're working with, only it's kind.

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

So in my little Angular2/Typescript program, I was trying to do the same:

webapp.module.ts:

webapp.module.ts:

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

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

tnsapp.module.ts:

tnsapp.module.ts:

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

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

这两个模块都使用不同的提供程序:TnsConfigurationServiceWebAppConfigurationService.

Both of these modules are using a different provider: TnsConfigurationService or WebAppConfigurationService.

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

However, these two @Injectable services implement the same interface:

configuration.interface:

configuration.interface:

export interface IConfigurationService {
    ...
}

最后,在我的一个组件中,我使用了我在开始时向您展示的这些模块之一提供的注入:

Finally, in one of my components, I use the injectable provided by one of these modules I showed you at the beginning:

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

export class HeroesService {

    constructor(private configurationService: IConfigurationService) { }
}

我的期望是最后一个组件被注入了正确的服务,即使参数只是明确地定义了接口.当然我得到一个错误(错误:无法解析 HeroesService 的所有参数")

My expectation was that this last component being injected with the right service, even though the parameter is only explicitely defining the interface. Of course I get an error ("Error: Can't resolve all parameters for HeroesService")

现在,我不希望有一个简单的解决方案,因为这听起来像是架构上的缺失.但也许有人可以指出我的替代设计?

Now, I don't expect an easy solution for this as it sounds as an architectural lack. But maybe someone can point me out to an alternative design?

推荐答案

为了注入一个提供者,它应该被注册为一个提供者.没有 IConfigurationService 提供程序.并且它不能是提供者,因为在编译的 JS 代码中不存在接口.

In order for a provider to be injected, it should be registered as a provider. There's no IConfigurationService provider. And it cannot be a provider, because interfaces don't exist in compiled JS code.

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

The common practice for interfaces that are supposed to be used as provider tokens is to be abstract classes:

abstract class ConfigurationService { ... }

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

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

这个秘籍通常被 Angular 2 本身使用,例如抽象NgLocalization具体的NgLocaleLocalization实现.

This recipe is commonly used by Angular 2 itself, e.g. abstract NgLocalization class and concrete NgLocaleLocalization implementation.

这篇关于Angular 2 可注入接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆