依赖注入框架 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 容器管理本模块依赖,然后在项目入口对所有的模块容器进行统一加载。

目录
相关文章
|
分布式计算 Ubuntu 调度
如何本地搭建DolphinScheduler并无公网ip远程访问管理界面
如何本地搭建DolphinScheduler并无公网ip远程访问管理界面
476 0
|
网络虚拟化
华为交换机批量加入 Vlan 方法
华为交换机单独加入vlan太麻烦,思科有批量加入vlan的方法,华为也有。要求 1~6口划分到vlan2,6~12口划分到vlan3,13~18口划分到vlan4,19~24口划分到vlan5.25,~26 加入trunk.
4077 0
|
6月前
|
Ubuntu Linux 开发工具
Ubuntu系统开发环境搭建和常用软件
Ubuntu系统作为一款优秀的开源Linux发行版,为开发者提供了强大的开发环境和丰富的软件资源。通过本文的介绍,相信读者已经对Ubuntu系统开发环境的搭建和常用软件有了一定的了解。在实际开发中,可以根据自己的需求进行选择和调整,以提高开发效率和体验。同时,随着Ubuntu系统的不断更新和发展,未来还将有更多优秀的软件和功能可供使用。
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
1409 6
|
SQL 运维 监控
面经:Presto/Trino高性能SQL查询引擎解析
【4月更文挑战第10天】本文深入探讨了大数据查询引擎Trino(现称Trino)的核心特性与应用场景,适合面试准备。重点包括:Trino的分布式架构(Coordinator与Worker节点)、连接器与数据源交互、查询优化(CBO、动态过滤)及性能调优、容错与运维实践。通过实例代码展示如何解释查询计划、创建自定义连接器以及查看查询的I/O预期。理解这些知识点将有助于在面试中脱颖而出,并在实际工作中高效处理数据分析任务。
1147 12
|
Python
在Python中,多分支结构(if-elif-else语句)
在Python中,多分支结构(if-elif-else语句)
1894 4
|
存储 JavaScript 前端开发
【面试官系列】React 中,如何在页面刷新之后保持状态?看看你知道几种~
【面试官系列】React 中,如何在页面刷新之后保持状态?看看你知道几种~
【面试官系列】React 中,如何在页面刷新之后保持状态?看看你知道几种~
|
数据采集 JSON Ubuntu
飞天加速计划·高校学生在家实践——教务系统查成绩Python爬虫程序
期末考试刚结束,查成绩需要登录到教务系统,比较繁琐。而成绩只有老师在系统中录入之后才能查到,我们也不知道老师什么时候录成绩,又很急着想知道每一门课的成绩。想到的解决办法就是24小时不停地访问教务系统,不停地查成绩。如果出了新的成绩,就给我发邮件。 之前写过一个教务系统Python爬虫程序,这次通过学生活动免费领取了阿里云的服务器,把Python程序放在服务器上定时运行,这让我成为班里每一门课都是第一个知道成绩的人
飞天加速计划·高校学生在家实践——教务系统查成绩Python爬虫程序
|
小程序
微信小程序wx.navigateTo跳转参数大小超出限制问题
微信小程序wx.navigateTo跳转参数大小超出限制问题
826 0