2016-08-02 72 views
2

我正在使用nodeJS + Typescript进行开发。我有一个面向对象的背景,我想从nodejs模块中受益,但是我正努力将它们与不应该是模块的类混合使用。如何使用Typescript和NodeJS将模块注入类中

这就是我想要做的事:

foo.ts(模块)

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(节点启动文件)

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

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

var bar = new Ns.Bar(foo) 

问题我面对试图构建这样的代码时:

  1. 酒吧无法看到。我试图添加对文件的引用,但它不起作用。
  2. 当我导入./foo时,“工作”,但当我这样做时无法看到在同一命名空间上定义的其他文件中的其他导出类型(即使我写入类型的全名,即包含命名空间,它仍然无法看到它)。
  3. 因此,我删除了命名空间Ns酒吧我可以看到其他类型时,我用命名空间键入其名称。但现在酒吧是一个模块,我觉得像我的构造注入气味,因为Foo是导入,我可以直接实例化它。

我不想强迫我的标准。我想知道我正在尝试做什么是正确的方法。这次斗争让我觉得我有义务在开发nodejs应用程序时重新设计并使用完整的模块。是对的吗?

如果我应该去完整的模块,我应该如何管理依赖注入?

谢谢

回答

1

为了充分利用的OOP功率(或者不如说Interface-based programming协议,面向对象编程),你应该使用interface Foo通过Bar类使用具体实施MyFoo的隐藏。

Foo.ts

export interface Foo { 
    fooMethod(): number; 
} 

MyFoo.ts

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

酒吧。TS

import {Foo} from './Foo' 

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

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

别的地方:

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

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

我个人不推荐使用的命名空间。你可以阅读更多关于命名空间和模块here

+0

我明白了你的观点。这种方法效果很好,它看起来很像推荐的方法。然而,在第一眼看来,这种模式让我觉得如果我使用许多小的粘性类(每个类都在一个单独的文件中)以及许多注入级别,我可能会遇到某种“导入地狱”。你知道这是否真的令人担忧? – Minduca

+1

你将有许多小模块(类),每个模块都将依赖于作为接口注入的许多其他模块(因为'class Bar'取决于'interface Foo')。而这个数字越小,模块的耦合程度就越低,软件的设计就越好。 – mixel

+0

很好的解释。再次感谢你。所以,我可以(1)为模块创建接口,并且即使在我打算为它实现单个实现时也具有接口的缺点,或者(2)绕过接口并导入和引用具体类型以利用智能感知,但具有将该类型加载到Bar范围的缺点,甚至不打算将其实例化。我的想法是否正确? – Minduca