inversify-inject-decorators

Lazy evaluated property injection decorators for InversifyJS

inversify-inject-decorators

Lazy evaluated property injection decorators.

Motivation

Some frameworks and libraries take control over the creation of instances of a given class. For example, React takes control over the creation of instances of a given React component. This kind of frameworks and libraries prevent us from being able to use constructor injectionand as a result they are not easy to integrate with InversifyJS.

InversifyJS also provides support for property injection but it also requires the instances of a class to be created by InversifyJS.

The decorators included in this library will allow you to lazy-inject properties even when the instances of a class cannot created by InversifyJS.

This library allows you to integrate InversifyJS with any library or framework that takes control over the creation of instances of a given class.

Installation

You can install inversify-inject-decoratorsusing npm:

$ npm install inversify inversify-inject-decorators reflect-metadata --save

The inversify-inject-decoratorstype definitions are included in the npm module and require TypeScript 2.0.

:warning: Please note that this library requires support for the ES6 Symbol. You can use the es6-symbol polyfillas a work arround.

Please refer to the InversifyJS documentationto learn more about the installation process.

Caching vs Non Caching Behaviour

By default, the lazy injection mechanism implemented by this will cache all requests to the underlying container. This means that rebinding or unbinding services to/from service identifiers will not be reflected in the instances into which these services have been injected into. The same holds true for scenarios where you dynamically load/unload container modules and thus either add or remove bindings from your container.

To overcome this limitation, one can now pass an additional boolean parameter to getDecorators(container: Container, doCache = true). When set to false, services resolved from the container will no longer be cached and will always be resolved from the container directly, e.g.

import { Container } from "inversify";
import getDecorators from "inversify-inject-decorators";

const container: Container = new Container();
const { lazyInject } = getDecorators(container, false);

Basic property lazy-injection with @lazyInject

The following example showcases how to inject into a property using the @lazyInjectdecorator:

import getDecorators from "inversify-inject-decorators";
import { Container, injectable, tagged, named } from "inversify";

let container = new Container();
let { lazyInject } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };

interface Weapon {
    name: string;
    durability: number;
    use(): void;
}

@injectable()
class Sword implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Sword";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

class Warrior {
    @lazyInject(TYPES.Weapon)
    public weapon: Weapon;
}

container.bind<Weapon>(TYPES.Weapon).to(Sword);

let warrior = new Warrior();
console.log(warrior.weapon instanceof Sword); // true

Named property injection with @lazyInjectNamed

The following example showcases how to inject into a named property using the @lazyInjectNameddecorator:

import getDecorators from "inversify-inject-decorators";
import { Container, injectable, named } from "inversify";

let container = new Container();
let { lazyInjectNamed } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };

interface Weapon {
    name: string;
    durability: number;
    use(): void;
}

@injectable()
class Sword implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Sword";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

@injectable()
class Shuriken implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Shuriken";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

class Warrior {

    @lazyInjectNamed(TYPES.Weapon, "not-throwwable")
    @named("not-throwwable")
    public primaryWeapon: Weapon;

    @lazyInjectNamed(TYPES.Weapon, "throwwable")
    @named("throwwable")
    public secondaryWeapon: Weapon;

}

container.bind<Weapon>(TYPES.Weapon).to(Sword).whenTargetNamed("not-throwwable");
container.bind<Weapon>(TYPES.Weapon).to(Shuriken).whenTargetNamed("throwwable");

let warrior = new Warrior();
console.log(warrior.primaryWeapon instanceof Sword); // true
console.log(warrior.primaryWeapon instanceof Shuriken); // true

Tagged property injection with @lazyInjectTagged

The following example showcases how to inject a tagged property using the @lazyInjectTaggeddecorator:

import getDecorators from "inversify-inject-decorators";
import { Container, injectable, tagged } from "inversify";

let container = new Container();
let { lazyInjectTagged } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };

interface Weapon {
    name: string;
    durability: number;
    use(): void;
}

@injectable()
class Sword implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Sword";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

@injectable()
class Shuriken implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Shuriken";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

class Warrior {

    @lazyInjectTagged(TYPES.Weapon, "throwwable", false)
    @tagged("throwwable", false)
    public primaryWeapon: Weapon;

    @lazyInjectTagged(TYPES.Weapon, "throwwable", true)
    @tagged("throwwable", true)
    public secondaryWeapon: Weapon;

}

container.bind<Weapon>(TYPES.Weapon).to(Sword).whenTargetTagged("throwwable", false);
container.bind<Weapon>(TYPES.Weapon).to(Shuriken).whenTargetTagged("throwwable", true);

let warrior = new Warrior();
console.log(warrior.primaryWeapon instanceof Sword); // true
console.log(warrior.primaryWeapon instanceof Shuriken); // true

Multi-injection into a property with @lazyMultiInject

The following example showcases how to multi-inject a property using the @lazyMultiInjectdecorator:

import getDecorators from "inversify-inject-decorators";
import { Container, injectable } from "inversify";

let container = new Container();
let { lazyMultiInject } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };

interface Weapon {
    name: string;
    durability: number;
    use(): void;
}

@injectable()
class Sword implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Sword";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

@injectable()
class Shuriken implements Weapon {
    public name: string;
    public durability: number;
    public constructor() {
        this.durability = 100;
        this.name = "Shuriken";
    }
    public use() {
        this.durability = this.durability - 10;
    }
}

class Warrior {

    @lazyMultiInject(TYPES.Weapon)
    public weapons: Weapon[];

}

container.bind<Weapon>(TYPES.Weapon).to(Sword);
container.bind<Weapon>(TYPES.Weapon).to(Shuriken);

let warrior = new Warrior();
console.log(warrior.weapons[0] instanceof Sword); // true
console.log(warrior.weapons[1] instanceof Shuriken); // true

HomePage

https://github.com/inversify/inversify-inject-decorators#readme

Repository

https+https://github.com/inversify/inversify-inject-decorators


上一篇:inversify-binding-decorators
下一篇:wildcard2

相关推荐

  • 聊聊Typescript中的设计模式——装饰器篇(decorators)

    随着Typescript的普及,在KOA2和nestjs等nodejs框架中经常看到类似于java spring中注解的写法。本文从装饰模式出发,聊聊Typescipt中的装饰器和注解。

    1 年前
  • 精读《Inject Instance 源码》

    1. 引言 本周精读的源码是 injectinstance(https://github.com/ascoders/injectinstance) 这个库。 这个库的目的是为了实现 Class ...

    1 年前
  • 小菜鸟之Vue - provide/inject不归路

    前言 为什么我要写这么一篇文章,网上不是一堆关于provide/inject的技术文章吗? 原因在于网上的那些博客大牛文章能完美避开坑,而我这篇文章描述是挖坑和埋坑的一个过程 provide/...

    10 个月前
  • 实现 VUE 中 MVVM - step13 - inject & 总结

    provide / inject 在上一步我们实现了,父子组件,和 一样 也是基于父子组件实现的,相比于 它的实现还要更简单一点。我们先来看看官网上对 的描述。

    2 年前
  • 在vue-class-component中使用provide和inject

    查了下官方文档没有给出使用案例,自己摸索了下。应该是写在@component里面,代码如下 ...

    1 个月前
  • 在Vue项目中,Provide,inject实现数据绑定

    不废话,直接正题 首先保证你的Vue版本支持Provide 下面两个简单组件我们来实现绑定 (/public/upload/617c7ed9aafa7df8582fc3d9bf823153) ...

    2 个月前
  • 介绍Provide以及Inject

    Provide 以及 Inject 是 Vue 中用于祖先元素向其所有后台元素注入依赖的接口。 具体用法 注意:通过 Inject 获得的属性是不可响应的。

    2 年前
  • webpack-inject-plugin

    A webpack plugin to dynamically inject code into the bundle. webpackinjectplugin All Contributors...

    8 个月前
  • vue的provide / inject 有什么用?

    1.前言 vue的父子组件通信用什么? 如果是爷孙组件呢? 如果是太爷爷和孙子组件呢? emmm 好的,没我啥事了,我这就走。 不行,我还能再挣扎一会儿!肯定有一部分兄弟做的项目比较小,组...

    7 个月前
  • vue的provide / inject

    vue的provide/inject provide/inject 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

    9 个月前

官方社区

扫码加入 JavaScript 社区