[英]Angular condition in type provider with AOT
我有一個Angular項目,我用AOT編譯。 我希望能夠注冊根據配置動態解析的ClassProvider
。 我使用的簡化代碼是這樣的:
const isMock = Math.random() > 0.5;
@NgModule({
// ...
providers: [
{ provide: MyServiceBase, useClass: (isMock) ? MyServiceMock : MyService },
],
bootstrap: [AppComponent]
})
export class AppModule { }
問題是當我用AOT編譯它時,我總是得到相同的服務。 我期望在擊中F5時獲得不同的服務(因為第一行的randomness
)。 在沒有AOT的情況下編譯時,它的行為與我期望的一樣。
以下是github上的完整代碼示例: https : //github.com/vdolek/angular-test/tree/aot-conditioned-provider-problem 。 它與ng serve
和ng serve --aot
行為不同 - ng serve --aot
。
我怎樣才能做到這一點? 我知道我可以使用FactoryProvider
,但我會重復的服務依存關系(工廠函數的參數和對財產的DEP FactoryProvider
)。
要實現需求的動態特性,您需要通過useFactory
屬性使用工廠提供程序 。
我已經分叉了您的存儲庫, 並按如下方式修改了您的app.module.ts ,以便在AOT中工作。
修改app.module.ts
如下
export let myServiceFactory = () => {
const isMock = Math.random() > 0.5;
return isMock ? new MyServiceMock() : new MyService();
};
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
{provide: MyServiceBase, useFactory: myServiceFactory},
],
bootstrap: [AppComponent]
})
export class AppModule {
}
在您的服務依賴於其他服務的情況下,您可以使用deps
參數來傳遞所需的依賴項。
假設MyServiceBase
依賴於兩個服務MyService1
和MyService2
......您的工廠函數將如下所示:
export let myServiceFactory = (service1:MyService1, service2:MyService2) => {
const isMock = Math.random() > 0.5;
return isMock ? new MyServiceMock(service1, service2) : new MyService(service1, service2);
};
並且您的提供商的審核將如下所示
providers: [
{
provide: MyServiceBase,
useFactory: myServiceFactory,
deps: [MyService1, MyService2]
},
]
本指南包含有關在Angular中實現依賴項注入的各種方法的更多詳細信息。
我認為@ jeanpaul-a說除了使用工廠之外別無選擇。 但是管理依賴關系可能不是很干凈。 但你可以使用的是注射器 。 我會用以下的東西:
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, HelloComponent ],
providers: [
Dep1Service,
Dep2Service,
{ provide: MyServiceBase, useFactory: createService, deps: [Injector] }
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
export function createService(injector: Injector) {
const isMock = Math.random() > 0.5;
if (mock) {
return new MyService1(injector.get(Dep2Service));
} else {
return new MyService2(injector.get(Dep1Service));
}
}
你還可以做的是將MyServiceBase設置為接口並使用InjectionToken 。 你會在這里找到一個有效的例子(不過你的班級名稱)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.