@zenweb/inject
v5.5.0
Published
Zenweb Inject module
Downloads
2,072
Readme
inject - 依赖注入
zenweb 依赖注入支持
依赖模块
无
配置项
此模块没有配置项
Core 挂载项
| 挂载项 | 类型 | 功能 | | ----- | --- | ---- | | injector | Injector | singleton 作用域注入管理器
Context 挂载项
| 挂载项 | 类型 | 功能 | | ----- | --- | ---- | | injector | Injector | request 作用域注入管理器
装饰器
| 名称 | 功能 | | --- | --- | | @Injectable | 业务类的构造参数注入 | @Init | 初始化方法 | @Inject | 属性注入
全局模式
| 方法 | 功能 | | ----- | ---- | | $getInstance(target: Class) | 取得对象实例,对象实例会优先从 request 层获取,没有请求上下文则从 singleton 层获取
样例代码
import { Init, Inject, Injector, Injectable } from '../src';
// 显示的标记为可被注入的类
// 构造函数有参数
// 设置类的作用域
// 注解默认级别为 request
@Injectable
class RequestClass1 {
s1test = '';
}
// 因为构造函数需要注入参数,所以必须添加 @Injectable 注解
@Injectable
class RequestInject {
constructor(
public s1: RequestClass1, // 第一次注入为一个新类
public s2: RequestClass1, // 第二次注入是第一次注入的实例
) {}
}
@Injectable
class RequestClass2 {
s2test = '';
constructor(
public s1: RequestClass1, // 有参数,必须添加注解才能被成功注入
public str: String, // 你甚至可以注入一个空字符串,道理就像上面说的,不添加注解默认就是 request 级别的可注入类
) {
s1.s1test = 'test for SimpleClass2';
}
}
// 一个没有任何注解的对象默认作用域为 prototype 级别,每次注入时都会被初始化,每一个注入对象都是新的
class PrototypeClass {
}
@Injectable
class PrototypeInject {
constructor(
public s1: PrototypeClass, // 每次注入都是一个新类
public s2: PrototypeClass, // 每次注入都是一个新类
) {}
}
// 标记类的作用域为单例类型,单例在整个应用周期只会初始化一次,不再销毁
// 例如数据库连接初始化,配置文件读取等只需要一次的场景
// 单例可以被任何级别注入
@Injectable('singleton')
class SingletonClass {
counter = 0; // 设置一个变量用于演示计数器不会被重置
// 使用 @Init 注解可以让类在初始化时执行一些异步操作,因为构造函数内不可以执行 await 操作符
@Init
private async init() {
this.counter = 1;
await new Promise((res) => setTimeout(res, 500));
this.counter = 2;
}
}
@Injectable
class BaseClass {
a = '';
constructor(
public singletonClass: SingletonClass,
) {}
@Init
protected init() {
this.a = 'inited';
}
}
// 继承类也会继承父类的作用域
class ExtendClass extends BaseClass {
b = '';
// 继承并不会阻碍父类的 init 调用
@Init
protected init() {
this.b = 'inited';
}
}
class InjectClass extends BaseClass {
// 因为父类使用了构造函数注入,这里再创建构造函数注入会变得繁琐,此时可以利用 @Inject 属性注入器避免了手动初始化父类问题
// 但是 @Inject 也有自己的坑,他在 new class 之后才进行属性注入,也就是说在构造函数中你不能访问属性,解决这个问题可以配合 @Init 注解器
@Inject s2!: RequestClass2;
// 使用 @Inject 避免了以下繁琐的操作
/*
constructor() {
// 当父类有构造器时,你必须要调用 super 方法
super(new SingletonClass()); // 错误,不应该自己初始化对象
}
*/
@Init
protected init() {
this.s2.s1.s1test = 'test for @Inject';
}
}