快速开始 Quickstart
在软件工程中,控制反转(IoC)和依赖注入(DI)是实现松耦合设计的重要原则和技术。本章节将演示如何在 TypeScript 中通过注解能力使用 IoC 和 DI。
技术原理
在TypeScript中,我们可以利用装饰器(Decorator)功能来创建自定义注解,实现IoC容器和依赖注入机制。
控制反转(IoC)
控制反转是一种设计原则,它改变了对象的获取依赖的方式。传统编程模式下,对象自行创建或查找所需的依赖对象,而在IoC中,对象的创建和依赖的查找由外部容器负责,对象只是声明其所需的依赖项。
依赖注入(DI)
依赖注入是实现IoC的一种方法,通过构造器、属性或方法将依赖关系注入到对象中,而不是由对象自身创建依赖。DI可以达到以下目标:
- 降低组件间的耦合度
- 增强组件的可测试性
- 提高代码的可维护性和扩展性
内置工具
Artus 中的 Core 实现底层基于 IoC(控制反转,Inversion of Control)实现,便于在上层框架中集成 DI(依赖注入,Dependency Injection)、AOP(面向切面编程,Aspect Oriented Programming)等特性(详见 loader 章节)。
为了便于用户使用,由 @artus/core
与 @artusx/koa
等包,提供对应的 decorator,简化在 typescript 中使用。
@artus/core
- Injectable
- Inject
@artusx/koa
- HTTPController
- Middleware
- POST / GET
使用示例
此处我们提供一个基于 koa 实现的 http-server 的简单示例,可点击链接查看完整代码。
https://github.com/artusjs/artusx/tree/main/packages/apps/artusx-koa (opens in a new tab)
Service
通过添加 Injectable 注解,可将对应的 class 注入到框架内置的容器中。
在 Core 中按照 Scope 提供 IOC Container 作为基础对象池,Scope 包括:
- Singleton(单例生命周期,全局执行一次实例化)
- Execution(执行生命周期,每次执行时实例化)
- Transient(临时生命周期,每次使用时实例化)
import { Inject, Injectable, ArtusInjectEnum, ArtusApplication } from '@artus/core';
@Injectable()
export default class APIService {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;
async mockApi() {
return {
data: {
name: 'artusx',
},
};
}
}
Controller
通过 HTTPController 相关注解,可将 route 以及 method 注入到 koa-router
;基于依赖注入的原则,在 controller 中,可通过 Inject 注解,将依赖的 service 注入。
Inject 支持通过 string 以及 clazz 方式在容器中查找依赖,可参考示例中的 config / service 的使用。
import { ArtusInjectEnum, Inject } from '@artus/core';
import { GET, HTTPController } from '../types';
import type { ArtusxContext } from '../types';
import APIService from './api.service';
@HTTPController('/api')
export default class APIController {
@Inject(ArtusInjectEnum.Config)
config: Record<string, string | number>;
@Inject(APIService)
apiService: APIService;
@GET('/')
async home(ctx: ArtusxContext) {
ctx.body = 'home';
}
@GET('/info')
async getInfo(ctx: ArtusxContext) {
ctx.body = await this.apiService.mockApi();
}
}