2016-03-03 1 views
6

Je suis sur le point d'utiliser un multi-provider pour exporter les dépendances de ma dépendance avec lui-même, afin qu'elles puissent être injectées dans un composant à la fois.Angular 2 multi-provider pour l'exportation des dépendances

Pour un composant

import {Component} from 'angular2/core'; 
import { FOO_PROVIDERS } from './foo'; 

@Component({ 
    selector: 'app', 
    providers: [FOO_PROVIDERS] 
}) 
export class App {} 

le following

import {Inject, Injectable, provide} from 'angular2/core'; 
import {Http, HTTP_PROVIDERS} from 'angular2/http'; 

export class Foo { 
    constructor(@Inject(Http) http) {} 
} 

export const FOO_PROVIDERS = [ 
    provide(Foo, { useClass: Foo, multi: true }), 
    provide(Foo, { useValue: HTTP_PROVIDERS, multi: true }) 
]; 

se traduira par

Aucun fournisseur pour Http! (App -> Foo -> Http)

Et this

import {Inject, provide} from 'angular2/core'; 
import {Http, HTTP_PROVIDERS} from 'angular2/http'; 

class Foo { 
    constructor(@Inject(Http) http) {} 
} 

export const FOO_PROVIDERS = [Foo, HTTP_PROVIDERS]; 

fonctionnera bien, alors que je les attendre à faire le même travail.

Y a-t-il une utilisation appropriée pour le multi-fournisseur dans ce cas?

+0

comme une note: un blocage que j'ai eu - assurez-vous de mettre FOO_PROVIDERS après avoir défini la classe FOO, pas avant – Tucker

+0

@Tucker C'est vrai, les classes ne sont pas levées – estus

Répondre

3

Lorsque vous vous inscrivez provide(Foo, ...), que vous pouvez

constructor(foo:Foo) 

avec multi: true vous êtes passé tous les fournisseurs enregistrés comme Foo

constructor(foo:any) 

Avec

export const FOO_PROVIDERS = [ 
    provide(Foo, { useClass: Foo, multi: true }), 
    provide(Foo, { useValue: HTTP_PROVIDERS, multi: true }) 
]; 

et

constructor(@Inject(Foo) foo:Foo[]) 

vous obtiendrez passé à foo un tableau contenant une instance de Foo et comme 2e point une liste de fournisseurs (ces contenus dans HTTP_PROVIDERS)

mise à jour

Peut-être que vous avez des attentes différentes de ce qui devrait arriver. Je ne vois pas comment @Inject(Http) http est lié ici. HTTP_PROVIDERS est enregistré uniquement en tant que valeur pour Foo. La valeur que vous transmettez à useValue est sans importance lorsque les fournisseurs sont résolus. DI recherche les fournisseurs pour Foo et a passé la valeur assignée et ne se soucie pas du tout de savoir quelle est cette valeur. Il n'y a pas de fournisseur pour Http dans votre exemple donc Foo lui-même n'a pas pu obtenir Http injecté.Vous devez vous enregistrer Http, qui se fait lorsque vous ajoutez HTTP_PROVIDERS directement aux fournisseurs (non en useValue) car HTTP_PROVIDERS contient Http (ce qui équivaut à provide(Http, {useClass: Http})

Update2

// An injected service that itself needs to get passed in a dependency 
@Injectable() 
class Foo { 
    constructor(private http:Http); 
} 

// container for a bunch of dependencies  
@Injectable() 
class MyProviders { 
    // add everything you want to make available in your components 
    constructor(public foo:Foo, public bar:Bar, ...); 
} 

class MyComponent { 
    // inject just MyProviders and use the dependencies it provides 
    constructor(private providers: MyProviders) { 
    // access provided values 
    providers.foo.doSomething(); 
    providers.bar.doSomethingElse(); 
    } 
} 

// Add all providers to allow DI to resolve all above dependencies 
bootstrap(AppComponent, [HTTP_PROVIDERS, Foo, Bar]); 

}

+0

Malheureusement, je ne peux pas vérifier cela. [This] (http://plnkr.co/edit/XyBBbb6smvq3ieH4fp1?p=preview) et [this] (http://plnkr.co/edit/nerxCcdwoju6MBplPXhI?p=preview) entraîneront l'injection d'une instance de Foo (avec ' constructeur (@Inject (Foo) foo) '), la seule différence est que Http ne peut pas être résolu dans le cas d'un fournisseur multiple. Et faire 'constructor (foo: Foo [])' lancerait 'Aucun fournisseur pour Array! (App -> Array) '. – estus

+0

Cela fonctionne bien dans votre premier Plunker si vous ajoutez 'FOO_PROVIDERS' aux fournisseurs de' App 'au lieu de 'Foo' http://plnkr.co/edit/mxet3Knfirnsf2jA0XGu?p=preview –

+0

En fait, il ne remarque pas, 'que @Inject (Http) http' a été délibérément commenté pour s'assurer que' foo' injecté n'est pas un tableau mais une instance de Foo. Avec la dépendance non commentée (le [premier exemple] (http://plnkr.co/edit/rNRalQnnkAPcTItmguW3?p=preview) dans la question) le problème est le même que décrit. Donc, on ne sait toujours pas ce qui ne va pas avec l'utilisation de plusieurs fournisseurs ici, et comment la réponse s'applique à la situation. – estus