2016-03-10 36 views
8

Scenario semplice:Iniettare tutti i servizi che implementano alcune interfacce

Possiedo più servizi che implementano un'interfaccia comune. Tutti questi servizi sono registrati nel metodo bootstrap.

Ora mi piacerebbe avere un altro servizio, che inietta tutti i servizi registrati che implementano l'interfaccia comune.

cioè

export interface MyInterface { 
    foo(): void; 
} 

export class Service1 implements MyInterface { 
    foo() { console.out("bar"); } 
} 

export class Service2 implements MyInterface { 
    foo() { console.out("baz"); } 
} 

export class CollectorService { 
    constructor(services:MyInterface[]) { 
     services.forEach(s => s.foo()); 
    } 
} 

Che è possibile in qualche modo?

risposta

7

È necessario registrare il proprio provider di servizi come questo:

boostrap(AppComponent, [ 
    provide(MyInterface, { useClass: Service1, multi:true }); 
    provide(MyInterface, { useClass: Service2, multi:true }); 
]); 

Questo funziona solo con le classi non con interfacce poiché le interfacce non esistono in fase di esecuzione.

Per farlo funzionare con le interfacce, è necessario adattarlo:

bootstrap(AppComponent, [ 
    provide('MyInterface', { useClass: Service1, multi:true }), 
    provide('MyInterface', { useClass: Service2, multi:true }), 
    CollectorService 
]); 

e iniettare in questo modo:

@Injectable() 
export class CollectorService { 
    constructor(@Inject('MyInterface') services:MyInterface[]) { 
    services.forEach(s => s.foo()); 
    } 
} 

Vai a questa plunkr per maggiori dettagli: https://plnkr.co/edit/HSqOEN?p=preview.

Vedere questo link per maggiori informazioni:

+0

grazie. proverò più tardi :) –

+0

Usa OpaqueToken, per favore vedi la risposta corretta http://stackoverflow.com/a/35916788/8363 – Schmuli

3

Poiché le interfacce non sono disponibili in fase di esecuzione (solo per i controlli statici) interfacce non possono essere utilizzati come toke per DI.

utilizzare un token invece: https://angular.io/api/core/OpaqueToken

var myInterfaceToken = new OpaqueToken('MyInterface'); 
// import `myInterfaceToken` to make it available in this file 

boostrap(AppComponent, [ 
    provide(myInterfaceToken, { useClass: Service1, multi:true }); 
    provide(myInterfaceToken, { useClass: Service2, multi:true }); 
]); 
// import `myInterfaceToken` to make it available in this file 

export class CollectorService { 
    constructor(@Inject(myInterfaceToken) services:MyInterface[]) { 
     services.forEach(s => s.foo()); 
    } 
} 
+0

Usare OpaqueToken è il modo consigliato di fornire implementazioni di interfaccia. – Schmuli

Problemi correlati