forze-deps-modules
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseForze dependency modules
Forze 依赖模块
Use when authoring or reviewing infrastructure wiring. For application bootstrap, see . For logical names and route values, see .
forze-wiringStrEnumforze-specs-infrastructure适用于编写或评审基础设施连接场景。如需了解应用启动相关内容,请查看。如需了解逻辑名称与路由值,请查看。
forze-wiringStrEnumforze-specs-infrastructureContainer model
容器模型
Deps| Mode | Shape | Use when |
|---|---|---|
| one provider per key | shared clients, secrets, idempotency defaults |
| one provider per key + route | specs resolved by |
| same provider for many routes | one backend supports several logical resources |
Deps.merge(...)CoreErrorDeps| 模式 | 结构 | 使用场景 |
|---|---|---|
| 每个键对应一个提供者 | 共享客户端、密钥、幂等性默认配置 |
| 每个键+路由对应一个提供者 | 通过 |
| 多个路由共用同一提供者 | 单个后端支持多个逻辑资源 |
Deps.merge(...)CoreErrorModule shape
模块结构
Built-in modules are generic over . Follow that pattern so callers can use names.
K: str | StrEnumStrEnumpython
from enum import StrEnum
from typing import Mapping, final
import attrs
from forze.application.contracts.base import DepKey
from forze.application.execution import Deps, DepsModule
WidgetClientDepKey = DepKey[WidgetClientPort]("widget_client")
WidgetDepKey = DepKey[WidgetDepPort]("widget")
@final
@attrs.define(slots=True, frozen=True, kw_only=True)
class WidgetDepsModule[K: str | StrEnum](DepsModule[K]):
client: WidgetClientPort
widgets: Mapping[K, WidgetConfig] | None = None
def __call__(self) -> Deps[K]:
plain = Deps[K].plain({WidgetClientDepKey: self.client})
routed = Deps[K]()
if self.widgets:
routed = Deps[K].routed(
{
WidgetDepKey: {
name: ConfigurableWidget(config=config)
for name, config in self.widgets.items()
}
}
)
return plain.merge(routed)内置模块基于实现泛型。请遵循此模式,以便调用者可以使用名称。
K: str | StrEnumStrEnumpython
from enum import StrEnum
from typing import Mapping, final
import attrs
from forze.application.contracts.base import DepKey
from forze.application.execution import Deps, DepsModule
WidgetClientDepKey = DepKey[WidgetClientPort]("widget_client")
WidgetDepKey = DepKey[WidgetDepPort]("widget")
@final
@attrs.define(slots=True, frozen=True, kw_only=True)
class WidgetDepsModule[K: str | StrEnum](DepsModule[K]):
client: WidgetClientPort
widgets: Mapping[K, WidgetConfig] | None = None
def __call__(self) -> Deps[K]:
plain = Deps[K].plain({WidgetClientDepKey: self.client})
routed = Deps[K]()
if self.widgets:
routed = Deps[K].routed(
{
WidgetDepKey: {
name: ConfigurableWidget(config=config)
for name, config in self.widgets.items()
}
}
)
return plain.merge(routed)Dep factories
依赖工厂
Most spec-backed adapters register factories shaped like:
python
def __call__(self, ctx: ExecutionContext, spec: WidgetSpec) -> WidgetPort:
return WidgetAdapter(client=ctx.deps.provide(WidgetClientDepKey), spec=spec, config=self.config)Application code resolves the factory with , then calls it with . convenience methods do this internally for documents, search, cache, counters, storage, locks, and embeddings.
route=spec.name(ctx, spec)ExecutionContext大多数基于规格的适配器会注册如下形式的工厂:
python
def __call__(self, ctx: ExecutionContext, spec: WidgetSpec) -> WidgetPort:
return WidgetAdapter(client=ctx.deps.provide(WidgetClientDepKey), spec=spec, config=self.config)应用代码通过解析工厂,然后传入调用它。的便捷方法会在内部针对文档、搜索、缓存、计数器、存储、锁和嵌入执行此操作。
route=spec.name(ctx, spec)ExecutionContextLifecycle stays separate
生命周期分离
Keep pure and cheap: it builds providers, not network connections. Initialize pools and clients in functions (, , , etc.).
DepsModule.__call__LifecycleSteppostgres_lifecycle_stepredis_lifecycle_steps3_lifecycle_step保持纯净且轻量化:它仅构建提供者,不创建网络连接。请在函数(如、、等)中初始化连接池和客户端。
DepsModule.__call__LifecycleSteppostgres_lifecycle_stepredis_lifecycle_steps3_lifecycle_stepRouted infrastructure
路由式基础设施
For tenant-aware clients, register a structural client port as a plain dependency and let routed clients choose the concrete connection at call time. For routed Postgres clients, pass when catalog metadata differs by tenant/database.
introspector_cache_partition_key对于支持租户的客户端,将结构化客户端端口注册为普通依赖,并让路由客户端在调用时选择具体连接。对于路由式Postgres客户端,当目录元数据因租户/数据库而异时,请传入。
introspector_cache_partition_keyAnti-patterns
反模式
- Instantiating adapters directly in handlers — use deps factories and ports.
- Using only strings in new modules — keep route type as .
K: str | StrEnum - Opening connections in — lifecycle owns startup/shutdown.
__call__ - Returning overlapping keys from multiple modules — compose maps before module construction or use distinct routes.
- Registering spec-backed providers as plain deps when multiple specs exist — use routed deps keyed by .
spec.name
- 在处理器中直接实例化适配器 — 请使用依赖工厂与端口。
- 在新模块中仅使用字符串 — 请将路由类型保持为。
K: str | StrEnum - 在中建立连接 — 生命周期负责启动/关闭操作。
__call__ - 从多个模块返回重叠键 — 请在模块构建前组合映射,或使用不同的路由。
- 当存在多个规格时,将基于规格的提供者注册为普通依赖 — 请使用以为键的路由式依赖。
spec.name
Reference
参考
src/forze/application/execution/deps.pysrc/forze/application/contracts/base/deps.pysrc/forze_postgres/execution/deps/module.pysrc/forze_redis/execution/deps/module.py
src/forze/application/execution/deps.pysrc/forze/application/contracts/base/deps.pysrc/forze_postgres/execution/deps/module.pysrc/forze_redis/execution/deps/module.py