校对:soup
TypeScript 基于模块的依赖性注射容器: 端口 为: 应用程序定义的词汇表, 供应商 绑定 a 端口到一个边缘的构造, 模块 组合他们,决定什么 外部看到——编译器能够捕捉的每一个接线错误都是编译 错误, 不是运行时的惊喜 .
pnpm add @btravstack/di unthrown
unthrown 是同级依赖. @btravstack/di 取决于其他的。 节点
>=22。 。 。 .
港口、供应商、模块
import { Module, Port, Provider } from "@btravstack/di";
import { ErrAsync, OkAsync, TaggedError, type AsyncResult } from "unthrown";
type Order = { readonly id: string; readonly total: number };
class OrderNotFound extends TaggedError("OrderNotFound")<{
readonly id: string;
}> {}
// A port is named by the domain, never by whatever will implement it.
class OrderRepository extends Port("OrderRepository")<{
readonly findById: (id: string) => AsyncResult<Order, OrderNotFound>;
}> {}
// A use case is a class that is its own port and provider: its services
// arrive typed on `this.deps`, under the names the `inject` record gave them.
class GetOrder extends Provider.class("GetOrder", { inject: { orders: OrderRepository } }) {
execute(id: string): AsyncResult<Order, OrderNotFound> {
return this.deps.orders.findById(id);
}
}
// An adapter is a provider binding a declared port to a construction.
const inMemoryOrders = Provider(OrderRepository)({
inject: {},
sync: () => {
const orders = new Map<string, Order>([["o-1", { id: "o-1", total: 42 }]]);
return {
findById: (id) => {
const order = orders.get(id);
return order === undefined
? ErrAsync(new OrderNotFound({ id }))
: OkAsync(order);
},
};
},
});
// A module groups providers and decides what the outside sees. `GetOrder`
// needs `OrderRepository`; a composition that forgets to provide it does not
// compile.
const Application = Module("Application")({
provides: [GetOrder, inMemoryOrders],
exports: [GetOrder],
});
// Build the graph, use it, tear it down — on every path.
await Module.scoped(Application, (ctx) => ctx.get(GetOrder).execute("o-1"));
模块的外部预期是从其提供者推断出来的 inject
记录并按其类型载运,所以入口拒绝留下的图表
一个没有供应,命名港口。 模块还可以说明其边界——
needs: [Logger] - 然后在自己的申报中加以核对.
五个供应商的武器—— value, (中文(简体) ), sync, (中文(简体) ), make (可能失败,有一个模型
错误), class, (中文(简体) ), acquire编号 :release (一种资源,在范围时释放)
(c) 个人违约模块, Port.many 用于插件注册,
Module.forkScope 以及编译时间的门
带着失踪的东西 文档网站。 。 。 .
下 @btravstack/core, (中文(简体) ), start(module) 这是
一个 Module.scoped 调用进程制作.
许可证
麻省理工学院 贝诺伊特旅行社