""" API 请求数据端口注册表。 """ from __future__ import annotations from collections.abc import AsyncGenerator, Callable, Generator from typing import Any SessionProvider = Callable[[], Generator[Any, None, None]] AsyncSessionProvider = Callable[[], AsyncGenerator[Any, None]] RepositoryFactory = Callable[[Any], Any] StandaloneFactory = Callable[[], Any] UnitOfWorkFactory = Callable[[Any], Any] class ApiDataPorts: """ 保存 API 依赖所需的会话、仓储和事务端口。 """ def __init__( self, *, sync_session: SessionProvider, async_session: AsyncSessionProvider, repositories: dict[str, RepositoryFactory], standalone: dict[str, StandaloneFactory], unit_of_work: dict[str, UnitOfWorkFactory], ) -> None: """ 保存由启动组合根提供的具体实现工厂。 """ self.sync_session = sync_session self.async_session = async_session self.repositories = repositories self.standalone = standalone self.unit_of_work = unit_of_work def repository(self, name: str, session: Any) -> Any: """ 按能力名构造请求级仓储。 """ return self.repositories[name](session) def standalone_repository(self, name: str) -> Any: """ 构造不绑定请求会话的持久化端口。 """ return self.standalone[name]() def transaction(self, name: str, session: Any) -> Any: """ 构造请求级事务端口。 """ return self.unit_of_work[name](session) _ports: ApiDataPorts | None = None def configure_api_data_runtime(ports: ApiDataPorts) -> None: """ 让旧全局 Facade 委托启动组合根创建的同一个端口实例。 """ global _ports _ports = ports def reset_api_data_runtime() -> None: """ 清除当前 lifespan 的 API 数据端口集合。 """ global _ports _ports = None def configure_api_data_ports( *, sync_session: SessionProvider, async_session: AsyncSessionProvider, repositories: dict[str, RepositoryFactory], standalone: dict[str, StandaloneFactory], unit_of_work: dict[str, UnitOfWorkFactory], ) -> None: """ 由启动组合根登记 API 数据实现,切断 API 对数据库实现包的直接导入。 """ configure_api_data_runtime(ApiDataPorts( sync_session=sync_session, async_session=async_session, repositories=repositories, standalone=standalone, unit_of_work=unit_of_work, )) def get_api_data_ports() -> ApiDataPorts: """ 返回当前 API 数据端口集合。 """ if _ports is None: raise RuntimeError("API 数据端口尚未由启动组合根配置") return _ports def get_db() -> Generator[Any, None, None]: """ 向 FastAPI 暴露同步请求会话依赖。 """ yield from get_api_data_ports().sync_session() async def get_async_db() -> AsyncGenerator[Any, None]: """ 向 FastAPI 暴露异步请求会话依赖。 """ async for session in get_api_data_ports().async_session(): yield session