工具集
Malagu 提供了一些工具集,用于简化开发。
Malagu 框架本身也是一个复杂的项目,在框架的实现过程中,逐渐积累了一些好用的工具。
autoBind
在我们使用 IoC 能力的时候,原始提供的手动绑定对象到容器中这种方式,这种方式操作比较繁琐。Malagu 框架通过在模块入口文件调用 autoBind
方法自动绑定对象到模块,并将模块对象返回。另外 autoBind
方法支持一个回调函数,在回调函数中,仍然可以使用原生手动绑定的方式(在一些特殊情况,仍然需要这种方式)。
// 某个模块入口文件
import "../common";
import { autoBind } from "@malagu/core";
import ".";
export default autoBind();
export const CoreBackendModule = autoBind((bind) => {
bind(VALUE).toDynamicValue((ctx) => {
const namedMetadata = ctx.currentRequest.target.getNamedTag();
const el = namedMetadata!.value.toString();
const configProvider = ctx.container.get<ConfigProvider>(ConfigProvider);
return configProvider.get(el);
});
});
ContainerUtil
Malagu 的核心基础设施是 IoC 容器,我们几乎把所有对象托管在 IoC 容器,让 IoC 容器负责这些对象的生命周期的管理。同时,框架也提供了一套装饰器 @Component()
、 @Autowired()
,帮助我们把对象托管到 IoC 容器中,以及从容器中取出需要的对象。但是,装饰器有个缺陷,只有使用 Class
才好用。 ContainerUtil
工具类就是为了解决某些特殊情况下,没法使用 Class
诞生的。通过该工具类,我们可以方便获取需要的对象。不过,使用 ContainerUtil
有一个限制:必须要在应用启动中或者应用启动完成后,方可以使用。非常典型的使用场景:React 函数组件中使用。
import * as React from "react";
import { ContainerUtil } from "@malagu/core";
import { IconResolver } from "./icon-protocol";
const { useState, useEffect, Fragment } = React;
export function Icon<T>(iconProps: T) {
const [iconNode, setIconNode] = useState<React.ReactNode>([]);
useEffect(() => {
const resolve = async () => {
const iconResolver = ContainerUtil.get<IconResolver<T>>(IconResolver);
setIconNode(await iconResolver.resolve(iconProps));
};
resolve();
}, [JSON.stringify(iconProps)]);
return <Fragment>{iconNode}</Fragment>;
}
ConfigUtil
Malagu 的应用配置属性是由所有依赖的组件的属性合并而成。通过配置属性,我们可以方便地改变框架的默认行为,而不需要修改一行代码。当我们想要获取一个属性值的时候,可以通过 @Value()
声明式获取某个属性值。与 ContainerUtil
存在同样的限制:非 Class
场景不友好。我们通过 configUtil
工具类就能很方便的在非 Class
场景中获取属性值。使用 ConfigUtil
也有一个限制:必须要在应用启动中或者应用启动完成后,方可以使用。
export function Logo(props: NavItemProps) {
const { label, icon, ...rest } = ConfigUtil.get("malagu.shell.logo");
props = { ...rest, ...props };
return <NavItem size="medium" gap="xsmall" label={label} icon={<Icon icon={icon} />} hoverIndicator={false} activatable={false} {...props} />;
}
AnnotationUtil
AnnotationUtil.getType
获取目标对象属性或方法中的参数的类型信息,示例代码如下:
AnnotationUtil.getType(target, targetKey, index); // 获取 target 对象中 targetKey 方法的第 index + 1 个参数的类型
AnnotationUtil.getType(target, targetKey); // 获取 target 对象中 targetKey 属性的类型
Prioritizeable
根据优先级大小对数组进行同步或异步排序。
Prioritizeable.prioritizeAllSync(this.contextInitializers).map((c) => c.value);
getSuperClasses
获取指定类的所有基类。
getOwnMetadata
获取指定类以及所有基类的相关元信息。
Deferred
延迟获取某一对象的包装类。示例代码如下:
const deferred = new Deferred(); // 创建 deferred 对象
deferred.resole(value); // 成功时调用
deferred.reject(error); // 失败时调用
deferred.promise; // 获取包装的 promise 对象
RequestMatcher
请求匹配器,支持 url 模式匹配。使用它可以验证当前请求的 url 是否符合某个 url 模式。该类的对象已经注入到 IoC 容器中,无需自己创建,请从容器中获取。
PathResolver
路径解析器。使用它可以把多个路径片段拼接到一起,它会帮您处理片段之间的/
问题,以及适当的情况下,自动附加上应用路由前缀。该类的对象已经注入到 IoC 容器中,无需自己创建,请从容器中获取。