2016-08-02 77 views
2

Ich entwickle in NodeJS + Typescript. Ich habe einen OO-Hintergrund und möchte von nodejs-Modulen profitieren, aber ich bemühe mich, sie mit Klassen zu kombinieren, die keine Module sein sollen.Wie man ein Modul in eine Klasse injiziert mit Typescript und NodeJS

Das ist, was ich versuche zu tun: (angeblich kein Modul sein)

foo.ts (Modul)

import http = require("http") 

export class Foo { 
    public fooMethod() : number { ... } 
} 

bar.ts

namespace Ns { 
    export class Bar { 
     constructor(private foo: Foo) { ... } //"Foo" is not being found by the intellisense 
     public barMethod() : number { 
      return this.foo.fooMethod() 
     } 
    } 
} 

server.js (Knoten Startup-Datei)

var Foo = import("./foo"); 

var foo = new Foo(); 
foo.configure(...)  //Configure foo before inject it into bar 

var bar = new Ns.Bar(foo) 

Probleme Ich bin vor, wenn sie versuchen, den Code so zu strukturieren:

  1. Bar nicht Foo sehen kann. Ich habe versucht, einen Verweis auf die Datei hinzuzufügen, aber es hat nicht funktioniert.
  2. Es funktionierte, wenn ich ./foo importierte, aber wenn ich das tue Bar kann andere exportierte Typen in anderen Dateien nicht sehen, die auf dem gleichen Namespace definiert sind (auch wenn ich den vollständigen Namen des Typs schreibe , dh den Namespace einschließen, er kann ihn immer noch nicht sehen).
  3. Also entfernte ich den Namespace Ns in Bar und ich konnte andere Typen sehen, wenn ich seinen Namen mit dem Namespace eintippte. Aber jetzt Bar ist ein Modul und ich es fühlt sich an wie mein Konstruktor Injektion riecht, da Foo importiert wird und ich es direkt instanziieren kann.

Ich will nicht meine Standards erzwingen. Ich möchte wissen, was der richtige Ansatz für das ist, was ich versuche. Der Kampf gibt mir das Gefühl, dass ich verpflichtet bin, bei der Entwicklung von nodejs-Anwendungen ein Redesign durchzuführen und volle Module zu absolvieren. Ist das richtig?

Für den Fall, dass ich volle Module gehen sollte, wie sollte ich Dependency-Injektion verwalten?

Danke

Antwort

1

voll Energie zu nutzen, von OOP (oder besser Interface-based programming oder zu sagen Protokoll orientierte Programmierung) Sie interface Foo verwenden sollten mit der spezifischen Implementierung MyFoo von Bar Klasse zu verstecken.

Foo.ts

export interface Foo { 
    fooMethod(): number; 
} 

MyFoo.ts

export class MyFoo { 
    fooMethod(): number { 
    return 1; 
    } 
} 

Bar.ts

import {Foo} from './Foo' 

export class Bar { 
    constructor(private foo: Foo) {} 

    barMethod(): number { 
    return this.foo.fooMethod(); 
    } 
} 

Irgendwo anders:

import {Boo} from './Boo' 
import {MyFoo} from './MyFoo' 

const result = new Boo(new MyFoo()).barMethod(); 

Persönlich empfehle ich nicht Namespaces zu verwenden. Sie können mehr über Namespaces und Module lesen here.

+0

Ich sehe Ihren Standpunkt. Dieser Ansatz funktioniert gut und es scheint wirklich wie empfohlen. Auf den ersten Blick scheint mir dieses Muster jedoch das Gefühl zu geben, dass ich, wenn ich mit vielen kleinen zusammenhängenden Klassen (jede Klasse in einer separaten Datei) und vielen Injektionsebenen arbeite, in eine Art "Import-Hölle" geraten könnte. Würdest du wissen, ob das ein echtes Problem ist? – Minduca

+1

Sie werden viele kleine Module (Klassen) haben und jeder von ihnen hängt von einer Anzahl anderer Module ab, die als Schnittstellen injiziert werden (da 'Klassenbalken' von' Schnittstellen-Foo' abhängt). Und je kleiner diese Zahl ist, desto niedriger sind Ihre Module und desto besser ist Ihre Software konzipiert. – mixel

+0

Schöne Erklärung. Danke nochmal. So kann ich (1) Schnittstellen für ein Modul erstellen und den Nachteil haben, Schnittstellen zu haben, selbst wenn ich eine einzige Implementierung dafür haben möchte, oder (2) die Schnittstelle umgehen und den konkreten Typ importieren und referenzieren, um intellisense zu nutzen der Nachteil besteht darin, den Typ in den Bereich von Bar zu laden, selbst wenn er nicht instanziiert werden soll. Sind meine Gedanken richtig? – Minduca