npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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,筛选出所有符合条件的事件。