ForcePilot/backend/package/yuxi/channels/infrastructure/dependency_injection.py
Kris b88c0ae29e feat(channels): 批量新增多渠道网关限界上下文基础代码与契约
新增完整的 channels 限界上下文模块,包含契约层、领域核心层、应用服务、管道编排、插件体系、基础设施组合根等全层级代码,新增飞书与微信 iLink 渠道插件基础结构,补充各类 DTO、端口协议与领域服务实现。
2026-07-02 03:22:12 +08:00

92 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""framework/bootstrap/dependency_injection.py依赖注入容器。
本模块是编排层的依赖注入装配点,负责管理 framework 层组件的单例注册
与解析。借鉴 external_systems 的 ``infrastructure/container.py`` 组合根
概念,但采用可变注册表形态以支持启动期分散注册、请求期按需解析。
设计原则:
- framework 层组件注册中心、EventBus、熔断器等为应用级单例跨请求复用
- 请求级组件(被驱动适配器、管道、用例服务)由各自 factory 按请求创建,不进入容器
(如 ``create_driven_adapters(db, outbox_config, redis_client, arq_pool, execution_port)``
与 ``InboundPipeline.create()`` / ``ControlPlanePipeline.create()`` /
``OutboundPipeline.create()``
- 容器仅负责应用级单例的注册与解析,保持职责单一
- 线程安全:所有读写操作通过 ``threading.Lock`` 串行化
"""
from __future__ import annotations
import threading
from typing import Any
from yuxi.channels.contract.errors import InternalError
__all__ = [
"DependencyInjectionContainer",
]
class DependencyInjectionContainer:
"""依赖注入容器。
管理 framework 层组件的单例注册,提供统一的依赖解析入口。
注册形态仅支持单例:由调用方在启动期直接传入已构造实例,
``resolve`` 时原样返回。未注册的接口解析失败抛出 ``InternalError``
因为这属于装配期编程错误(漏注册),而非客户端请求的资源不存在。
线程安全:所有注册与解析操作通过同一把 ``threading.Lock`` 串行化,
保证并发场景下注册表的读写一致性。
典型用法::
container = DependencyInjectionContainer()
container.registerSingleton(EventBus, InMemoryEventBus())
container.registerSingleton(PluginRegistry, PluginRegistry())
event_bus = container.resolve(EventBus)
plugin_registry = container.resolve(PluginRegistry)
"""
def __init__(self) -> None:
"""初始化依赖注入容器。
创建空的单例注册表与互斥锁。
"""
self._singletons: dict[type, Any] = {}
self._lock = threading.Lock()
def registerSingleton(self, interface: type, instance: Any) -> None:
"""注册单例。
将已构造的实例绑定到指定接口类型,后续 ``resolve`` 直接返回该实例。
若同一接口已注册,则覆盖原有绑定。
Args:
interface: 接口类型(通常为 Protocol 或抽象基类),作为解析键。
instance: 已构造的实例,将作为单例原样返回。
"""
with self._lock:
self._singletons[interface] = instance
def resolve(self, interface: type) -> Any:
"""解析依赖。
返回绑定到该接口的单例实例。若接口未注册,抛出 ``InternalError``。
Args:
interface: 接口类型(通常为 Protocol 或抽象基类),作为解析键。
Returns:
绑定到该接口的单例实例。
Raises:
InternalError: 该接口未注册单例(装配期漏注册,属编程错误)。
"""
with self._lock:
if interface not in self._singletons:
raise InternalError(
message=f"Dependency not registered: {interface.__name__}",
)
return self._singletons[interface]