inject-provide
v0.3.8
Published
a light nodejs tool to inject and provide class
Downloads
7
Readme
Inject-Provide
inject-provide
是一个极简洁的 nodejs 注入框架,运行过程中需要装饰器的支持,建议使用 TypeScript 作为运行环境。
安装
npm install inject-provide --save
基本使用
inject-provide
的使用方法非常简单,只有 7 个 API。
注入: Inject, AutoInjected
提供:Provide, Offer
注册:createStore
默认库:rootStore
注入库工具类:storeController
事件处理:createEvent
创建注入库
import { createStore } from "inject-provide";
export newStore = createStore("newStore");
这一步创建过程是可选的,inject-provide
已经构建了一个默认的根注入库,即 rootStore
,在所有不指明的注入 store 都会默认注入到 rootStore
中。
提供类
import { Provide, rootStore } from "inject-provide";
import { newStore } from "./my-store";
@Provide({
name: symbol("ProvideCar")
store: [newStore, rootStore],
args: ["BMW"]
})
class ProvideCar {
constructor(public name: string) {}
getName() {
return this.name;
}
}
其中,Provide
的 name 参数是可选的,为空的时候会将类的 toString() 形式作为注入的令牌注入到 rootStore
中。
Provide
的 store 参数是可选的,为空的时候会注入到 rootStore
中,支持传入数组和单个 Store,但是在数组中如果仍希望注入到 rootStore
则需要手动加入。
Provide
的 args 参数也是可选的,args 即为构造函数中未被注入的参数,按顺序暴露在 args 参数数组中,在提交到注入库的时候会被初始化。
使用注入服务
import { Inject } from "inject-provide";
import { ProvideCar } from "./provide-car";
import { newStore } from "./my-store";
class UseCar {
constructor(@Inject(ProvideCar, newStore) public car: ProvideCar) {}
getCarName() {
return this.car.getName();
}
}
其中,Inject
的第一个参数是令牌,建议使用类名作为令牌,为空的时候会注入到 rootStore
中。
第二个参数为目标的注入库,inject-provide
会在在该库中查找待注入的数据,默认为 rootStore
。
使用自动注入
import { AutoInject } from "inject-provide";
import { UseCar } from "./use-car";
const result = AutoInject(UseCar);
result.getCarName(); //BMW
进阶技巧
参数注入
在构造函数中,如果有多个需要注入和不注入的参数,要把需要注入的参数放在前面
import { Inject } from "inject-provide";
import { ProvideCar } from "./provide-car";
class UseCar {
constructor(
@Inject(ProvideCar) public car: ProvideCar,
public ownerAge: number,
public ownerName: string // 不需要Inject的放在后面
) {}
getCarName() {
return this.car.getName();
}
}
非注入的处理
自动注入时,不在注入服务中的参数按顺序写在后面
import { AutoInject } from "inject-provide";
import { UseCar } from "./use-car";
const result = AutoInject(UseCar, 25, "Alice");
result.getCarName(); //BMW
result.ownerAge === 25; // true
主动注入 Offer
通过 Offer
, 可以使用直接提供服务的方式,为其他类型提供注入功能
import { Offer } from "inject-provide";
import { newStore } from "./my-store";
const obj = {
name: "Bob",
age: 20
};
Offer(obj, {
store: newStore
}); // 直接注入obj对象的地址
默认情况下,Offer 会使用 new 方法来初始化一个函数类型 (ES5 类),如果你希望注入一个纯粹的函数,那么请使用 pure 参数,来表明这是一个简单的函数
import { Offer } from "inject-provide";
import { newStore } from "./my-store";
const add = (num: number) => num + 1;
Offer(add, {
store: newStore,
pure: true // 是一个函数
}); // 直接注入obj对象的地址
storeController 处理 store
storeController 是 store 的工具类,提供了一些对 store 的处理工具:
create 同 createStore
exist 判断目标 store 是否存在
is 判断目标 store 是合理的 Store 的对象
count 获取所有store个数
事件注入
示例
import { createEvent } from "inject-provide";
const mainEvent = createEvent("Test");
@mainEvent.Subject()
class Test {
@mainEvent.Provider()
sayHello() {
console.log("hello, world");
}
}
mainEvent.controller.emit(); //hello,world
createEvent
createEvent
函数会返回一个 EventInjector
类的一个实例,包含一个事件类装饰器、事件方法装饰器、事件控制器、事件注入库、事件标签装饰器。
declare class EventInjector {
store: Store;
controller: EventController;
constructor();
Subject(): (...args: any[]) => (target: any) => void;
Provide(): () => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
Tag(): (tag?: string | undefined) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
}
Subject
Subject
对一个类进行装饰,该类的方法可以成为事件的注入类
import { createEvent } from "inject-provide";
const mainEvent = createEvent("Test");
@mainEvent.Subject()
class Test {
}
Provider
Provider
对一个类的实例方法进行装饰,该类的方法会被注入到事件控制器中
import { createEvent } from "inject-provide";
const mainEvent = createEvent("Test");
@mainEvent.Subject()
class Test {
@mainEvent.Provider()
sayHello() {
console.log("hello, world");
}
}
Tag
Tag
对一个类的实例方法进行装饰,该类的方法会被加上一个标签,可以被控制器筛选
import { createEvent } from "inject-provide";
const mainEvent = createEvent("Test");
@mainEvent.Subject()
class Test {
@mainEvent.Tag('main')
@mainEvent.Provider()
sayHello() {
console.log("hello, world");
}
}
所有没有被 Tag
标记的所有方法在控制器库中的 tag
属性都为 null
,所有不存在 tag
属性(为 undefined
)的方法都不会被控制器识别。
controller
controller
是一个类的控制器
import { createEvent } from "inject-provide";
const mainEvent = createEvent("Test");
@mainEvent.Subject()
class Test {
@mainEvent.Tag('main')
@mainEvent.Provider()
sayHello() {
console.log("hello, world");
}
@mainEvent.Provider()
sayThanks() {
console.log("Thanks");
}
}
mainEvent.controller.emit(); //hello,world, Thanks
mainEvent.controller.tagSelector((tagName) => tagName.includes('m')).emit();
// only "hello, world"
controller
的一些方法:
emit
激活所有标记的事件
tagSelector
接受一个函数、字符串或者null,筛选出所有符合条件的事件。