依赖注入框架 InversifyJS

简介:

背景

面向对象有五大原则:单一职责、开闭原则、里氏替换、接口分离和依赖反转。依赖反转(Dependency Inversion),实体应该依赖于抽象而不是实现。也就是说高层次模块,不应该依赖于低层次模块,而是应该基于抽象。

WebIDE 是函数计算团队研发的一款产品,为了解决函数计算本地环境差异和配置繁琐的问题。WebIDE 前端是 monorepo 风格的项目,即插件化构建 WebIDE 前端。插件之间存在依赖关系。构建、扩展和以及使用一个插件将是一个复杂的问题,而且对使用插件的开发人员不透明。通过使用 inversify 就能很简单的实现。通过 inversify 能很容的实现插件的构建、扩展和使用。

  • 创建。将服务类注入到容器中
  • 替换。通过 rebind api 可以在其他模块中从新绑定某个服务
  • 使用。在类中通过装饰器注入需要使用的服务,服务的具体实现不需要关心,容器为我们管理

需要了解 WebIDE 详情,请移步:WebIDE 使用手册

介绍

InversifyJS 是一个轻量级的依赖注入框架,大小只有 4KB,可以用于 Javascript 应用中。

安装

由于 InversifyJS 用到了反射来获取装饰器的相关元数据,所以需要额外安装库 reflect-metadata

npm install inversify reflect-metadata --save

另外,InversifyJS 要求 Typescript >= 2.0 并且需要配置如下编译参数:

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es6", "dom"],
        "types": ["reflect-metadata"],
        "module": "commonjs",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
    }
}

使用

步骤 1:定义接口

// file interfaces.ts

// 定义服务对象标识
export const Warrior = Symbol.for('Warrior');
export const Weapon = Symbol.for('Weapon');
export const ThrowableWeapon = Symbol.for('ThrowableWeapon');

export interface Warrior {
    fight(): string;
    sneak(): string;
}

export interface Weapon {
    hit(): string;
}

export interface ThrowableWeapon {
    throw(): string;
}

步骤 2:定义依赖

// file entities.ts

import { injectable, inject } from 'inversify';
import 'reflect-metadata';
import { Weapon, ThrowableWeapon, Warrior } from './interfaces';

@injectable()
export class Katana implements Weapon {
    public hit() {
        return "cut!";
    }
}

@injectable()
export class Shuriken implements ThrowableWeapon {
    public throw() {
        return "hit!";
    }
}

@injectable()
export class Ninja implements Warrior {

    public constructor(
        @inject(Weapon) protected katana: Weapon,
        @inject(ThrowableWeapon) protected shuriken: ThrowableWeapon
    ) {}

    public fight() { return this.katana.hit(); }
    public sneak() { return this.shuriken.throw(); }

}

步骤 3:创建并配置 IOC 容器

// file inversify.config.ts

import { Container } from "inversify";
import { Warrior, Weapon, ThrowableWeapon } from "./interfaces";
import { Ninja, Katana, Shuriken } from "./entities";

const myContainer = new Container();
myContainer.bind<Warrior>(Warrior).to(Ninja);
myContainer.bind<Weapon>(Weapon).to(Katana);
myContainer.bind<ThrowableWeapon>ThrowableWeapon).to(Shuriken);

export { myContainer };

步骤4:依赖解析

import { myContainer } from "./inversify.config";
import { Warrior } from "./interfaces";

const ninja = myContainer.get<Warrior>(Warrior);

expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true

小结

如果你熟悉 Spring,Spring 很多特性在 Inversify 中可以找到,如果你的项目规模比较大,可以采用 monorepo 多包结构来构建项目。每一个包(模块)包含一个 ContainerModule 容器管理本模块依赖,然后在项目入口对所有的模块容器进行统一加载。

目录
相关文章
|
机器学习/深度学习 数据可视化 算法
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
|
架构师 Java
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
346 0
|
前端开发 JavaScript UED
React 滚动条组件 Scrollbar
本文介绍了在 React 中创建和使用滚动条组件的方法。首先,通过设置 `overflow: auto` 等 CSS 属性实现基础滚动功能。接着,推荐了如 `react-custom-scrollbars` 和 `react-perfect-scrollbar` 等第三方库以增强滚动条的功能与外观。针对常见问题,如样式不一致、无法正常工作及性能瓶颈,提供了相应的解决方案,包括自定义样式、确保容器高度和优化渲染逻辑。最后,强调了避免滚动事件绑定错误和不合理嵌套滚动的重要性,帮助开发者打造流畅、美观的用户界面。
807 16
|
缓存 前端开发 JavaScript
React 必学SSR框架——next.js
​ 首先我们就回顾一下,我们到底是怎么告别了使用 php/jsp 做服务器端渲染,进入前后端分离的客户端渲染时代,又为什么重新回到了服务端渲染。
3267 0
|
数据采集 算法 搜索推荐
数据挖掘实战:基于KMeans算法对超市客户进行聚类分群
数据挖掘实战:基于KMeans算法对超市客户进行聚类分群
3514 0
|
数据采集 BI 数据库
MyEMS的安装部署与数据读取查看
MyEMS开源能源管理系统用于建筑、工厂、商场、医院、园区的电、水、气等能源数据采集、分析、报表,还有光伏、储能、充电桩、微电网、设备控制、故障诊断、工单管理、人工智能优化等可选功能。资深专业团队开发维护,保障长期支持。用开源助力实现碳达峰碳中和目标!
|
缓存 前端开发 JavaScript
探索 Qt WebEngineWidgets:从底层原理到高级应用与技巧
探索 Qt WebEngineWidgets:从底层原理到高级应用与技巧
2359 0
|
缓存 NoSQL Java
Redis实现商品信息对象缓存
Redis实现商品信息对象缓存
546 0
|
小程序 前端开发 JavaScript
开题报告--基于微信小程序的村务管理系统的设计与开发
开题报告--基于微信小程序的村务管理系统的设计与开发
330 0
|
Web App开发 缓存 前端开发

热门文章

最新文章