2016-12-08 2 views
0

In meiner App Angular 2 habe ich eine Anforderung, wo ich einen von zwei abgeleiteten Typen für einen bestimmten Basistyp zur Laufzeit registrieren muss. Ich kam damit auf:Wie Injektor von Provider Factory

In meinem Modul verwende ich eine Provider Factory. Der Konstruktor von ApiService benötigt den eckigen Http-Dienst und meinen eigenen ConfigService, darum ist die deps-Eigenschaft bestimmt.

// imports omitted 

let appContentBranchValue = 'myApp'; 

@NgModule({ 
    bootstrap: [AppComponent], 
    declarations: [ 
     AppComponent 
    ], 
    imports: [ ... ], 
    providers: [ 
     { provide: 'AppContentBranch', useValue: appContentBranchValue }, 
     { provide: ApiService, 
      deps: [Http, ConfigService], 
      useFactory: ApiServiceProviderFactory.create(appContentBranchValue) }, 
    ] 
}) 
export class MyAccountModule { } 

In meiner Typoskript Service-Klasse, vor der Definition von ApiService und seinen abgeleiteten Typen, habe ich diese Fabrik Umsetzung Provider.

Ich habe die Implementierung hier hauptsächlich, um die Logik zu halten, wie zwischen ApiServiceMock und ApiServiceReal aus dem Modul zu wählen. Wenn ein bestimmter LocalStorage-Schlüssel vorhanden ist und einen Truthy-Wert hat, erstellt die Factory ApiServiceMock und gibt ApiServiceReal andernfalls zurück.

export class ApiServiceProviderFactory { 
    public static create = (appContentBranch: string) => { 
     let factory = (http: Http, configService: ConfigService): ApiService => { 

      let flagKey = appContentBranch + '.mock.api'; 
      let flagValue = localStorage.getItem(flagKey); 

      if (flagValue && JSON.parse(flagValue)) { 
       return new ApiServiceMock(http, configService); 
      } else { 
       return new ApiServiceReal(http, configService); 
      } 
     }; 
     return factory; 
    }; 
} 

Statt Http und ConfigService in meiner Fabrik Funktion übergeben, ist es möglich, den Injektor wie dies stattdessen passieren?

 let factory = (injector: InjectorOfSomeKind): ApiService => { 

      let flagKey = appContentBranch + '.mock.api'; 
      let flagValue = localStorage.getItem(flagKey); 

      if (flagValue && JSON.parse(flagValue)) { 
       return injector.get(ApiServiceMock); 
      } else { 
       return injector.get(ApiServiceReal); 
      } 
     }; 
     return factory; 
    }; 
} 

Wenn ich dies tun könnte, dann kann das schmutzige Geschäft, wie man den Konstruktor aufruft, vollständig vermieden werden.

Kann dies getan werden? Grüße, Ian.

+0

verwenden können, was bedeutet 'InjectorOfSomeKind' bedeuten ?. –

+0

OK, ich meinte Injektor von angular/core. – IanT8

Antwort

0

Einfach injizieren injector:Injector und dann injector.get(ApiService) verwenden.

Zum Testen Sie

TestBed.configureTestingModule({ 
     providers: [{provide: ApiService, useClass: ApiServiceMock}] 
    }); 
Verwandte Themen