比nestjs更优雅的ts控制反转策略-依赖查找
一、Cabloy5.0内测预告
Cabloy5.0采用TS对整个全栈框架进行了脱胎换骨般的大重构,并且提供了更加优雅的ts控制反转策略,让我们的业务开发更加快捷顺畅
1. 新旧技术栈对比:
| 后端 | 前端 | |
|---|---|---|
| 旧版 | js、egg2.0、mysql | js、vue2、framework7 |
| 新版 | ts、egg3.0、多数据库兼容(支持mysql、postgresql) | ts、vue3、quasar |
2. 框架开发两大趋势
TS化:这是显而易见的趋势,不必赘言
ESM化:从目前趋势看,前端框架已经全链路ESM化了,但是,大多数后端框架仍然是Commonjs。即便是egg3.0也仍然是Commonjs。由于egg的定位仍然是元框架,CabloyJS5.0在egg基础上仍然开发出了全量ESM化的业务模块化系统(在Commonjs之上进行ESM化的具体机制是什么,另有文章阐述)
二、比nestjs更优雅的ts控制反转策略
基于TS的后端框架一般都会提供依赖容器,实现控制反转。控制反转有两种策略:依赖注入和依赖查找。CabloyJS5.0同时支持依赖注入和依赖查找,并且通过模块范围的辅助,让依赖查找的代码更加简洁高效,下面挑几个特性举例说明:
- Service服务
- Config配置
- 多语言
- 错误异常
三、Service服务
1. 创建一个Service
在CabloyJS中,local bean相当于nestjs中service的概念,下面创建一个local bean
import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
@Local()
export class LocalHome extends BeanBase<ScopeModule> {
async echo({ user: _user }) {
return `Hello World!`;
}
}
通过
@Local声明LocalHome是一个local beanLocalHome继承自基类BeanBase
2. Service的依赖注入
接下来,在Controller中采用依赖注入的方式来使用LocalHome
import { BeanBase, Controller, Use } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
import { LocalHome } from '../local/home.js';
@Controller()
export class ControllerHome extends BeanBase<ScopeModule> {
@Use()
home: LocalHome;
async echo() {
const res = await this.home.echo({
user: this.ctx.state.user.op,
});
this.ctx.success(res);
}
}
- 使用
@Use注入LocalHome
3. Service的依赖查找
接下来,在Controller中采用依赖查找的方式来使用LocalHome
import { BeanBase, Controller } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
@Controller()
export class ControllerHome extends BeanBase<ScopeModule> {
async echo() {
const res = await this.scope.local.home.echo({
user: this.ctx.state.user.op,
});
this.ctx.success(res);
}
}
- 不需要导入LocalHome,直接在代码中使用
this.scope.local来访问容器中的local bean实例
看一下动画演示,提供了完整的类型智能提示:

四、Config配置
1. 定义Config
可以为业务模块单独定义一些Config配置,如下:
import { CabloyApplication } from '@cabloy/core';
export const config = (_app: CabloyApplication) => {
return {
+ prompt: 'hello world',
};
};
2. 使用Config
可以在LocalHome中直接使用刚才定义的config
import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
@Local()
export class LocalHome extends BeanBase<ScopeModule> {
async echo({ user: _user }) {
+ return this.scope.config.prompt;
- return `Hello World!`;
}
}
- 不需要导入任何类型,直接在代码中使用
this.scope.config来访问当前业务模块中的config配置
看一下动画演示,提供了完整的类型智能提示:

五、多语言
1. 定义语言资源
可以为业务模块定义语言资源,比如,这里分别定义英文和中文两种语言资源
英文
export default {
HelloWorld: 'Hello World',
};
中文
export default {
HelloWorld: '您好世界',
};
2. 使用语言资源
可以在LocalHome中直接使用刚才定义的语言资源
import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
@Local()
export class LocalHome extends BeanBase<ScopeModule> {
async action({ user: _user }) {
+ // 自动判断当前语言
+ const message = this.scope.locale.HelloWorld();
+ // 强制使用英文资源
+ const message1 = this.scope.locale.HelloWorld.locale('en-us');
+ // 强制使用中文资源
+ const message2 = this.scope.locale.HelloWorld.locale('zh-cn');
+ return `${message}:${message1}:${message2}`;
- return this.scope.config.prompt;
}
}
- 不需要导入任何类型,直接在代码中使用
this.scope.locale来访问当前业务模块中的语言资源
看一下动画演示,提供了完整的类型智能提示:

六、错误异常
1. 定义错误码
可以为业务模块定义错误码
export enum Errors {
+ Error001 = 1001,
}
- 这里定义了一个错误枚举类型Error001,对应的错误码是1001
2. 定义错误码对应的语言资源
可以为错误码定义语言资源,比如,这里分别定义英文和中文两种语言资源
英文
export default {
+ Error001: 'This is a test',
HelloWorld: 'Hello World',
};
中文
export default {
+ Error001: '这是一个错误',
HelloWorld: 'Hello World',
};
3. 抛出错误异常
可以在LocalHome中直接使用刚才定义的错误枚举值,并抛出异常
import { ScopeModule } from '../resource/this.js';
@Local()
export class LocalHome extends BeanBase<ScopeModule> {
async action({ user: _user }) {
+ // 直接抛出异常
+ this.scope.error.Error001.throw();
- return this.scope.config.prompt;
}
}
- 不需要导入任何类型,直接在代码中使用
this.scope.error来访问当前业务模块中的错误枚举值
看一下动画演示,提供了完整的类型智能提示:

六、后记
Cabloy4.0中就已经提供了大量业务能力,比如:工作流引擎、表单引擎、权限引擎、字段权限、多级缓存、模块化体系、分布式架构、多租户引擎,等等。随着Cabloy5.0 Typescript的赋能,这些业务能力也随之有了全新的表现
欲了解更多,请关注每晚8点B站直播:濮水代码
比nestjs更优雅的ts控制反转策略-依赖查找的更多相关文章
- 轻松了解Spring中的控制反转和依赖注入(一)
我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...
- 简单了解Spring的控制反转和依赖注入
浅谈控制反转(Inversion of Control,IOC) 我们首先先来了解一下控制二字,也就是在控制"正"转的情况下,在任何一个有请求作用的系统当中,至少需要有两个类互相配 ...
- Spring中的控制反转和依赖注入
Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...
- .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用
再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...
- Java之控制反转和依赖注入
1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...
- Java 控制反转和依赖注入模式【翻译】【整理】
Inversion of Control Containers and the Dependency Injection pattern --Martin Fowler 本文内容 Component ...
- java控制反转与依赖注入
1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...
- [.net 面向对象程序设计深入](26)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)
[.net 面向对象程序设计深入](26)实战设计模式——使用IoC模式(控制反转或依赖注入)实现松散耦合设计(1) 1,关于IOC模式 先看一些名词含义: IOC: Inversion of con ...
- spring学习总结一----控制反转与依赖注入
spring作为java EE中使用最为广泛的框架,它的设计体现了很多设计模式中经典的原则和思想,所以,该框架的各种实现方法非常值得我们去研究,下面先对spring中最为重要的思想之一----控制反转 ...
- [.net 面向对象程序设计深入](31)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)
[.net 面向对象程序设计深入](31)实战设计模式——使用IoC模式(控制反转或依赖注入)实现松散耦合设计(1) 1,关于IOC模式 先看一些名词含义: IOC: Inversion of con ...
随机推荐
- 【Azure Redis 缓存】使用StackExchange.Redis,偶发ERROR - Timeout performing HSET (15000ms)
问题描述 使用StackExchange.Redis 作为Redis客户端SDK,连接Azure Redis服务,长期运行后发现,每天都偶发 Timeout Error. 错误消息如下: StackE ...
- 【Azure 微服务】Azure Service Fabric 因证书问题而使得 Node 一直处于 Down 状态
问题描述 Service Fabric 集群更新证书后,重启Node后就变为Down的状态,反复 Restart 结果反复Down 问题分析 根据Service Fabric的文档表示,修改证书时一定 ...
- Python 潮流周刊第 40 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- For 循环跟yield区别?
for循环遍历一个万亿级别的长列表,会将这个列表的全部数据载入到内存中去,如果你的内存很小就会溢出,即使是内存很大,这个操作也是十分占用资源的. 而使用生成器,则会将数据的状态(例如:遍历到列表的哪个 ...
- 2.UML类图基本介绍
1. UML 基本介绍 UML--Unified modeling language UML(统一建模语言),是一种用于软件系统分析和设计的语言工具,它用于帮助软件开发人员进行思考和记录思路的结果 U ...
- 按值传递,引用传递 浅析java String ,对象与对象引用的区别
目录 一.前言 二.何谓对象? 三.何谓对象引用? 四.创建对象 Vehicle veh1 = new Vehicle(); 五.参数传值 六.Java Sting 最后!有错误的地方欢迎指正 一.前 ...
- MYSQL索引-上
前言 今天同事做数据清理的时候发现我这边有一张表没有主键,这个表有两个字段,ID和Name,ID作者唯一索引,在我印象里,一个数据表如果没有主键索引,它会内部创建主键索引,创建的标准就是唯一性,我觉得 ...
- SyntaxError: invalid property id(就是不支持ES6) (浏览器不支持对象...展开)
SyntaxError: invalid property id(就是不支持ES6) (浏览器不支持对象...展开) 火狐55以后支持
- vitepress 发布到 gitee上的build命令 自动设置base
docs.vitepress\config.js const argv = require('minimist')(process.argv.slice(2)) const build = argv. ...
- 【线段树】【leetcode 729. 我的日程安排表 I】
class MyCalendar { class Seg { int l; int r; boolean val; Seg left; Seg right; public Seg(int x, int ...