今天我偶然发现了一些我认为不会给我带来麻烦的事情.
在Java和Spring中,我可以声明两个bean都实现一个给定的接口,而在另一个注入它们的类中我只使用接口; 这实际上就是我对IoC的喜爱:你真的不必知道你正在使用什么对象,只有它是善良的.
所以在我的小Angular2/Typescript程序中,我试图做同样的事情:
webapp.module.ts:
...
import { WebAppConfigurationService } from './app/services/webapp.configuration.service';
@NgModule({
...
providers: [WebAppConfigurationService]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
tnsapp.module.ts:
...
import { TnsConfigurationService } from './services/tns.configuration.service';
@NgModule({
...
providers: [TnsConfigurationService]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
这两个模块都使用不同的提供程序:TnsConfigurationService或WebAppConfigurationService.
但是,这两个@Injectable服务实现了相同的接口:
configuration.interface:
export interface IConfigurationService {
...
}
Run Code Online (Sandbox Code Playgroud)
最后,在我的一个组件中,我使用了我在开始时向您展示的其中一个模块提供的注入:
import { IConfigurationService } from './configuration.interface';
export class HeroesService {
constructor(private configurationService: IConfigurationService) { }
}
Run Code Online (Sandbox Code Playgroud)
我的期望是最后一个组件注入了正确的服务,即使参数只是明确定义了接口.当然我收到一个错误("错误:无法解析HeroesService的所有参数")
现在,我不希望有一个简单的解决方案,因为它听起来像一个架构缺乏.但也许有人可以指出我的替代设计?
dependency-injection interface inversion-of-control typescript angular
我有一个用 AOT 编译的 Angular 项目。我希望能够注册ClassProvider根据配置动态解析的内容。我使用的简化代码是这样的:
const isMock = Math.random() > 0.5;
@NgModule({
// ...
providers: [
{ provide: MyServiceBase, useClass: (isMock) ? MyServiceMock : MyService },
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
问题是当我用 AOT 编译它时,我总是得到相同的服务。我希望在点击 F5 时获得不同的服务(因为randomness在第一行)。在没有 AOT 的情况下编译时,它的行为符合我的预期。
这是 github 上的整个代码示例:https : //github.com/vdolek/angular-test/tree/aot-regulation-provider-problem。它的行为与ng serve和不同ng serve --aot。
我怎样才能做到这一点?我知道我可以使用FactoryProvider,但是我必须复制服务依赖项(工厂函数的参数和 deps 上的属性FactoryProvider)。