Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
904 views
in Technique[技术] by (71.8m points)

typescript - Angular 2 Injectable Interface?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...