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

better-inject

v1.3.3

Published

node typescript depend inject

Downloads

28

Readme

基于 typescript 的模仿 spring 依赖注入和面向切面

依赖注入

  1. 支持注解 3 个,自动扫描@Resource 注入构造函数参数@inject 注入对象类型的构造函数参数@injectObj
  2. 支持配置文件
  3. 支持同时注解和配置文件
  4. 循环依赖检测
  5. 可扫描文件注解文件和配置文件,支持**和*占位符
  6. 支持继承父亲构造函数注入
  7. 支持工厂类,继承 factoryBean 类,默认获取 getObject 返回对象;可通过&id 获取工厂对象自身
  8. 获取实例时候可动态传参数覆盖注解或配置文件的参数
  9. 支持 factoryBean 特性
  10. 支持接口类型注入
  11. 目前只支持构造函数注入

面向切面

  1. 提供注解 Aspect Before After Around AfterReturn AfterThrow PointCut
  2. 提供配置文件,使用Checker校验
  3. Aspect 的类必须同时使用Resource标记为 bean
  4. 配置文件的 adviceId 如果省略,默认为 aspectId
  5. Before After Around 的对应方法,只有一个 Invoker 类型的参数. AfterThrow 和 AfterReturn 有第二个参数,分别是返回值和抛出的错误。
  6. 注解模式的全局切点:如果一个类标记了 PointCut,但是没有标记 Advice,会把这些 PointCut 作为全局切点
  7. Aspect(number)设置优先级,数字>=0,数字越小优先级越高。
  8. 默认优先级都是 0,相同优先级的切面按照 Around Before After AfterReturn AfterThrow 的顺序执行,不同切面优先级不同的按照优先级先执行。比如有两个切面 a1 和 a2. a1: around1 before1 after1 afterReturn1 a2: around2 before2 after2 afterReturn2

如果 a1 和 a2 优先级相同,执行顺序为 around1-start around2-start before1 before2 原生方法 around2-end around1-end after2 after1 afterReturn2 afterReturn1 但是具体是 around1-start 先还是 around2-start 先不一定。如果一个是配置文件,一个是注解的,那么配置文件先,否则不一定

如果 a1 优先级 0 a2 优先级 1,则为 around1 before1 around2 before2 原生方法 around2-end after2 afterReturn2 around1-end after1 afterReturn1

安装

npm install better-inject

使用

有一个service类,依赖dao类,依赖jdbc类。
下面的例子通过注解扫描到service和dao类。
通过配置文件定义jdbc类。
然后通过getBean获取到注入后的service实例。

// 主文件
import Context from 'better-inject'

const root = '绝对路径地址'
const context = new Context({
  // 注解目标文件扫描
  // 如果是相对路径,相对于root地址解析
  // 占位符包含** 和 *
  // **在目录中间代表目录下所有文件
  // *在文件地址中表示正则.*
  scanFiles: [
    'service.ts',
    'dao.ts',
    // 这个含义是查找test目录下,第一层所有目录下的*.ts文件
    'test/**/*.ts'
  ],
  // 配置文件扫描
  configFiles: 'config.ts',
  root,
});
console.log(context.get('service'))


// service.ts
import { Resource } from 'better-inject';
import Dao from './dao';

@Resource(/** 默认 type: prototype id: 类名 parent: 无**/)
// 内部生成类似service: {dao: Dao}的定义数据
class Service {
  private dao: Dao;
  // 这里如果没有@Inject,会获取Dao类,并默认要注入一个id为dao的对象
  // 如果你想注入一些别的东西或者Dao是一个接口,必须使用配置文件或Inject
  // 注解主动注入
  constructor(@Inject('oracledao')dao: Dao) {
    this.dao = dao;
  }

  getDao() {
    return this.dao;
  }
}
export default Service;

// Dao.ts
import { Resource } from 'better-inject';
import Jdbc from './jdbc';

@Resource({type: 'single'})
export default class Dao {
  private jdbc: Jdbc;
  constructor(jdbc: Jdbc) {
    this.jdbc = jdbc;
  }

  getJdbc() {
    return this.jdbc;
  }
}

// Jdbc.ts
export default class Jdbc {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

// config.ts 可以通过配置文件定义全部数据关系,
import Jdbc from './jdbc';
import {Checker} from '../../context';
// 可以不使用Checker,直接导出,但是这样就没有ts数据格式校验
export default Checker([
  {
    // id,对应getBean()的参数
    id: 'jdbc',
    // 别名,对应getBean()的参数
    alias: ['Jdbc', 'JDBC'],
    // 这个bean对应类
    beanClass: Jdbc,
    // 构造函数参数直接值
    constructParams: {
        // 位置
        0: {
          // 值
          value: 'oracle',
          // 表示把这个value看做id,用于注入
          isBean: true,
        }
    },
    // 构造函数参数使用对象merge
    constructParams: {
        // 位置 表示注入一个对象,包含jdbc和name
        两个属性,会和getBean的参数进行merge,getBean参数优先级高
        0: [{
          jdbc: {
            // 值
            value: 'oracle',
            // 表示把这个value看做id,用于注入
            isBean: true,
          },
          name: {
            value: 'zcs',
          },
        }]
    },
    // 实例化类型 single 单例模式 prototype 原型模式 默认是prototype
    type: 'single'
  },
]);

注意

  1. context 的 root 默认是 process.cwd()

Resouce 内部逻辑

  1. 把这个类标记成一个可通过容器获取的目标,把类名小写作为 id。
  2. 然后会读取类中的构造函数参数,如果认为某个构造函数是类,就会自动把它认为是一个依赖注入项,把这个类的类名小写作为要注入的 id。或者通过 inject 标签主动注入,inject 的值默认认为是 id。