Angular 2 Injectable Interface?

房东的猫 提交于 2019-12-29 01:42:11

问题


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

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.

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

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

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

However, these two @Injectable services implement the same 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) { }
}

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?


回答1:


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 }]
...

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



来源:https://stackoverflow.com/questions/42422549/angular-2-injectable-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!