2016-03-20 10 views
1

Ich habe die Angular 2.0 docs über Abhängigkeit Inversion gelesen und ich habe auch einige online examples gesucht.Angular 2.0 DI kann ich mich auf Abstraktionen verlassen?

Mein Verständnis ist, dass der @injectable Dekorator den TypeScript-Compiler mit dem Flag emitDecoratorMetadata verwendet, um Metadaten zu erstellen, die zum Auflösen von Abhängigkeiten verwendet werden. Nehmen Sie zum Beispiel die folgende Klasse:

enter image description here

Typoskript Compiler emitDecoratorMetadata über Metadaten zu erklären, verwendet, die die DataService Klasse einen Konstruktor Argument hat mit Typ Http.

Sobald wir die Abhängigkeiten einer Klasse deklariert haben @Injectable verwenden, können wir zeigen, dass es in einigen Komponenten injiziert werden muss, die Provides Option in den @App oder @Component Dekorateure verwenden.

enter image description here

Ich bin mir dessen bewusst das Verhalten von emitDecoratorMetadata und ich weiß, dass es keine Metadaten für Schnittstellen emittieren kann. Daher gehe ich davon aus, dass ich nicht auf IHttp statt Http verlassen kann:

enter image description here

Ist meine Annahme richtig? Kann ich davon abhängen “Depend upon Abstractions. Do not depend upon concretions.” oder ist das etwas, das im Moment nicht möglich ist? Ich nehme an, das wird behoben werden, sobald die emitDecoratorMetadata Serialisierung von Schnittstellen wird.

Antwort

3

Momentan benötigen Sie einen Typ, einen String-Namen oder einen OpaqueToken als Schlüssel für Provider.
Schnittstellen werden nicht unterstützt, da die Informationen zur Laufzeit nicht verfügbar sind. Wenn das hinzugefügt wird, bin ich sicher, dass DI sie unterstützen wird (es wird bereits von Dart unterstützt).

+0

Wenn ich eine Zeichenfolge verwende, wie und wo ich die Zeichenfolge auf den tatsächlichen Typ zuordnen? –

+3

Anstatt nur einen Typ zu den Providern in 'bootstrap()' oder Komponenten hinzuzufügen, verwenden Sie 'provide ('someName', {useClass: Http}])' und im Konstruktor '@Inject ('someName') http: IHttp' –

1

Wenn Sie TypeScript verwenden, habe ich eine Lösung für Sie.

Ich verwende nicht Angular 2.0, aber wir entwickelten ähnliche DI-Bibliothek (intakejs). Das Problem ist, dass TS-Compiler Reflection-Metadaten nur für Klassen ausgeben, nicht für Interfaces (sie werden wie "Objekt" behandelt).

Hoffentlich würden sie solche Funktionalität weiter hinzufügen, aber heute verwenden wir Hack basierend auf TypeScript declaration merging Funktion. Die Idee ist, dass Sie Schnittstelle erklären können, und führen Sie sie mit einer Schnur oder einer anderen Laufzeit-ID wie folgt aus:

export interface IMyInjectable { 
    foo(): string; 
} 
export const IMyInjectable = 'MyInjectable'; 

Nehmen wir an, Sie Implementierung dieser Schnittstelle haben:

@Injectable('MyInjectable') 
class MyInjectable implements IMyInjectable { 
    foo(): string { return 'hello' } 
} 

Dann können Sie hängen von Abstraktion in Ihrer Verbraucherklasse:

Ich hoffe, dass dieser kleine Trick Ihr Problem lösen wird.

+0

Sieht interessant aus. Der 'Injizable'-Decorator unterstützt keine Parameter wie' @Injectable ('MyInjectable') ', obwohl https://github.com/angular/angular/blob/758efba34bb347991991e780ed31130e642e65ab/modules/angular2/src/core/di/decorators.dart # L23. Ist das notwendig? –

+0

Wie ich bereits erwähnt habe, habe ich Angular DI nie benutzt. Aber ich könnte annehmen, dass '@ Injectiable' eine Laufzeit-ID mit dem Namen der Klasse erstellt, so dass Sie versuchen können, Ihre Schnittstelle mit diesem Namen zu verbinden. – koroandr

+0

Ok, danke für deine Gedanken :) –