在节点的情况下打字稿 IOC

Typescript IOC in case of node

我想知道您将如何使用 typescript IOC 特别是节点应用程序。

external module-based architecture 的情况下,应用程序中没有任何 class。只是纯模块,因为我的应用严重依赖 node_modules.

在这种情况下,我将如何集成 IOC 解决方案?有什么想法吗?

这是我想使用 IOC 的具体案例:

我有猫鼬模型:

interface IStuffModel extends IStuff, mongoose.Document { }   

var Stuff= mongoose.model<IStuffModel>('Stuff', Schemas.stuffSchema);

export = Stuff;

及相关假货class:

export class Stuff implements IStuff { 
 //do stuff
}

How would I integrate IOC solution in such case

这是我推荐的一个非常流行的库:https://github.com/inversify/InversifyJS

外部模块

使用外部模块根本不会改变代码。而不是

kernel.bind(new TypeBinding<FooBarInterface>("FooBarInterface", FooBar));

生产

你刚刚

import {ProdFooBar} from "./prodFooBar";
kernel.bind(new TypeBinding<FooBarInterface>("FooBarInterface", ProdFooBar));

测试

import {MockFooBar} from "./mockFooBar";
kernel.bind(new TypeBinding<FooBarInterface>("FooBarInterface", MockFooBar));

正如 Basarat 在他的回答中指出的那样,我开发了一个名为 InversifyJS 的 IoC 容器,它具有上下文绑定等高级依赖注入功能。

您需要遵循 3 个基本步骤 才能使用它:

1。添加注释

注释API基于Angular 2.0:

import { injectable, inject } from "inversify";

@injectable()
class Katana implements IKatana {
    public hit() {
        return "cut!";
    }
}

@injectable()
class Shuriken implements IShuriken {
    public throw() {
        return "hit!";
    }
}

@injectable()
class Ninja implements INinja {

    private _katana: IKatana;
    private _shuriken: IShuriken;

    public constructor(
        @inject("IKatana") katana: IKatana,
        @inject("IShuriken") shuriken: IShuriken
    ) {
        this._katana = katana;
        this._shuriken = shuriken;
    }

    public fight() { return this._katana.hit(); };
    public sneak() { return this._shuriken.throw(); };

}

2。声明绑定

绑定 API 基于 Ninject:

import { Kernel } from "inversify";

import { Ninja } from "./entities/ninja";
import { Katana } from "./entities/katana";
import { Shuriken} from "./entities/shuriken";

var kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);

export default kernel;

3。解决依赖关系

分辨率API基于Ninject:

import kernel = from "./inversify.config";

var ninja = kernel.get<INinja>("INinja");

expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true

最新版本 (2.0.0) 支持许多用例:

  • 内核模块
  • 内核中间件
  • 使用 classes、字符串文字或符号作为依赖标识符
  • 常量值注入
  • class 构造函数注入
  • 工厂注入
  • 汽车厂
  • 供应商注入(异步工厂)
  • 激活处理程序(用于注入代理)
  • 多次注射
  • 标记绑定
  • 自定义标签装饰器
  • 命名绑定
  • 上下文绑定
  • 友好例外(例如循环依赖)

您可以在 https://github.com/inversify/InversifyJS

了解更多信息

在 Node.js 的特定上下文中有 a hapi.js example that uses InversifyJS