inversify-vanillajs-helpers

原文链接

一些使用原生JS或Babel开发InversifyJS的辅助方法。

安装

npm install inversify-vanillajs-helpers
1

使用

import { helpers } from "inversify-vanillajs-helpers";
1
var helpers = require("inversify-vanillajs-helpers").helpers;
1

注释助手

当您使用原生JS时,让您不必一次次手动去注释。一般来说是这样:

inversify.decorate(inversify.injectable(), Ninja);
inversify.decorate(inversify.inject(TYPES.Katana), Ninja, 0);
inversify.decorate(inversify.inject(TYPES.Shuriken), Ninja, 1);
1
2
3

现在只要这样写就可以了:

helpers.annotate(Ninja, [TYPES.Katana, TYPES.Shuriken]);
1

我们来看一个实例:

var inversify = require("inversify");
var helpers = require("inversify-vanillajs-helpers").helpers;
require("reflect-metadata");

var TYPES = {
  Ninja: 'Ninja',
  Katana: 'Katana',
  Shuriken: 'Shuriken'
}

class Katana {
  hit () {
    return 'cut!'
  }
}

helpers.annotate(Katana);

class Shuriken {
  throw () {
    return 'hit!'
  }
}

helpers.annotate(Shuriken);

class Ninja {

  constructor(katana, shuriken) {
      this._katana = katana;
      this._shuriken = shuriken;
  }

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

}

helpers.annotate(Ninja, [TYPES.Katana, TYPES.Shuriken]);

// Declare bindings
var container = new inversify.Container()
container.bind(TYPES.Ninja).to(Ninja);
container.bind(TYPES.Katana).to(Katana);
container.bind(TYPES.Shuriken).to(Shuriken);

// Resolve dependencies
var ninja = container.get(TYPES.Ninja);
console.log(ninja.fight(), ninja.sneak());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

具名注释

您还可以使用annotation方法声明具名元数据:

helpers.annotate(
    Ninja,
    [
        { type: TYPES.Katana, named: "not-throwable" },
        { type: TYPES.Shuriken, named: "throwable" }
    ]
);
1
2
3
4
5
6
7

带标签的注释

您还可以使用annotate方法声明带标签的元数据:

helpers.annotate(
    Ninja,
    [
        { type: TYPES.Katana, tagged: { key: "throwable", value: false } },
        { type: TYPES.Shuriken, tagged: { key: "throwable", value: true } }
    ]
);
1
2
3
4
5
6
7

注册helper

有了这些辅助方法,您用原生JS开发时再也不必重复地声明注释和注册模板了:

inversify.decorate(inversify.injectable(), Ninja);
inversify.decorate(inversify.inject(TYPES.Katana), Ninja, 0);
inversify.decorate(inversify.inject(TYPES.Shuriken), Ninja, 1);
container.bind(TYPES.Ninja).to(Ninja);
1
2
3
4

只需要这样既可:

let register = helpers.register(container);
register(TYPES.Ninja, [TYPES.Katana, TYPES.Shuriken])(Ninja);
1
2

当开发者使用了Babel时,该helper仍旧可以作为类装饰器:

let register = helpers.register(container);

@register(TYPES.Ninja, [TYPES.Katana, TYPES.Shuriken])
class Ninja {

  constructor(katana, shuriken) {
      this._katana = katana;
      this._shuriken = shuriken;
  }

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

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

请看下面这个例子:

var inversify = require("inversify");
var helpers =  require("inversify-vanillajs-helpers").helpers;
require("reflect-metadata");

var TYPES = {
  Ninja: 'Ninja',
  Katana: 'Katana',
  Shuriken: 'Shuriken'
}

class Katana {
  hit () {
    return 'cut!'
  }
}

class Shuriken {
  throw () {
    return 'hit!'
  }
}

class Ninja {

  constructor(katana, shuriken) {
      this._katana = katana;
      this._shuriken = shuriken;
  }

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

}

// Declare bindings
var container = new inversify.Container();
var register = helpers.register(container);
register(TYPES.Katana)(Katana);
register(TYPES.Shuriken)(Shuriken);
register(TYPES.Ninja, [TYPES.Katana, TYPES.Shuriken])(Ninja);

// Resolve dependencies
var ninja = container.get(TYPES.Ninja);
console.log(ninja.fight(), ninja.sneak());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

以此类推,许多类型绑定都可以采取这种方式。

registerSelf

var registerSelf = helpers.registerSelf(container);
registerSelf()(Katana);
1
2

registerConstantValue

var registerConstantValue = helpers.registerConstantValue(container);
registerConstantValue(TYPES.Katana, new Katana());
1
2

registerDynamicValue

var registerDynamicValue = helpers.registerDynamicValue(container);
registerDynamicValue(TYPES.Katana, (context) => { new Katana(); });
1
2

registerConstructor

var registerConstructor = helpers.registerConstructor(container);
registerConstructor(TYPES.Katana)(Katana);
1
2

registerFunction

var registerFunction = helpers.registerFunction(container);
registerFunction(TYPES.SomeFunction, () {
  console.log("I'm doing something...");
});
1
2
3
4

registerAutoFactory

var registerAutoFactory = helpers.registerAutoFactory(container);
registerAutoFactory(TYPES.KatanaFactory, TYPES.Katana);
1
2

registerFactory

var registerFactory = helpers.registerFactory(container);
registerFactory(TYPES.KatanaFactory, (context) => {
  return () => {
    return context.container.get("Katana");
  };
});
1
2
3
4
5
6

registerProvider

var registerProvider = helpers.registerProvider(container);
registerProvider(TYPES.KatanaProvider, (context) => {
    return () => {
        return new Promise<Katana>((resolve) => {
            let katana = context.container.get("Katana");
            resolve(katana);
        });
    };
});
1
2
3
4
5
6
7
8
9

声明绑定约束

辅助函数register方便您连续绑定声明API:

var register = helpers.register(container);

register(TYPES.Weapon, (b) => {
    b.whenTargetTagged("throwable", false);
})(Katana);

register(TYPES.Weapon, (b) => {
    b.whenTargetTagged("throwable", true);
})(Shuriken);

register(TYPES.Ninja, [
  { tagged: { key: "throwable", value: false }, type: "Weapon" },
  { tagged: { key: "throwable", value: true }, type: "Weapon" }
])(Ninja);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Babel 装饰器

即便使用了Babel也一样可以使用register辅助函数作为类的装饰器,使用transform-decorators-legacy插件即可。

let helpers = require("inversify-vanillajs-helpers").helpers;
let inversify = require("inversify");
require("reflect-metadata");

let container = new inversify.Container();
let register = helpers.register(container);

let TYPE = {
    Warrior: "Warrior",
    Weapon: "Weapon"
};

@register(
    TYPE.Weapon, [],
    (b) => { b.whenTargetTagged("throwable", false); }
)
class Katana {
    constructor() {
        this.name = "Katana";
    }
}

@register(
    TYPE.Weapon, [],
    (b) => { b.whenTargetTagged("throwable", true); }
)
class Shuriken {
    constructor() {
        this.name = "Shuriken";
    }
}

@register(
    TYPE.Warrior,
    [
        { tagged: { key: "throwable", value: false }, type: TYPE.Weapon },
        { tagged: { key: "throwable", value: true }, type: TYPE.Weapon }
    ]
)
class Ninja {
    constructor(primaryWeapon, secondaryWeapon) {
        this.primaryWeapon = primaryWeapon;
        this.secondaryWeapon = secondaryWeapon;
    }
}

let ninja = container.get(TYPE.Warrior);
expect(ninja.primaryWeapon.name).to.eql("Katana");
expect(ninja.secondaryWeapon.name).to.eql("Shuriken");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

演示Demo

您可以在这找到Demo

var helpers = require("inversify-vanillajs-helpers").helpers;
var inversify = require("inversify");
require("reflect-metadata");

class Katana {
    constructor() {
        this.name = "Katana";
    }
}

class Shuriken {
    constructor() {
        this.name = "Shuriken";
    }
}

class Ninja {
    constructor(primaryWeapon, secondaryWeapon) {
        this.primaryWeapon = primaryWeapon;
        this.secondaryWeapon = secondaryWeapon;
    }
}

let container = new inversify.Container();
let register = helpers.register(container);
 
let TYPE = {
    Warrior: "Warrior",
    Weapon: "Weapon"
};

register(TYPE.Weapon, [], (b) => b.whenTargetTagged("throwable", false))(Katana);
register(TYPE.Weapon, [], (b) => b.whenTargetTagged("throwable", true))(Shuriken);

register(TYPE.Warrior, [
    { tagged: { key: "throwable", value: false }, type: TYPE.Weapon },
    { tagged: { key: "throwable", value: true }, type: TYPE.Weapon }
])(Ninja);
 
container.get(TYPE.Warrior);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
上次更新: 1/14/2020, 4:49:04 PM