from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from src.application.abstractions import IUnitOfWork from src.application.abstractions.repositories import IOrderRepository,IPaymentRepository,IUserRepository from src.application.contracts import ILogger from src.infrastructure.database.repositories.order_repository import OrderRepository from src.infrastructure.database.repositories.payment_repository import PaymentRepository from src.infrastructure.database.repositories.user_repository import UserRepository class UnitOfWork(IUnitOfWork): def __init__(self, session_factory: async_sessionmaker[AsyncSession], logger: ILogger): self.session_factory = session_factory self._session: AsyncSession = None self._order_repository: IOrderRepository | None = None self._payment_repository: IPaymentRepository | None = None self._user_repository: IUserRepository | None = None self._logger: ILogger = logger async def __aenter__(self): self._session = self.session_factory() self._order_repository = None self._payment_repository = None self._user_repository = None return self async def __aexit__(self, exc_type, exc_val, exc_tb): if exc_type: self._logger.error(str(exc_val)) await self._session.rollback() self._logger.error(f'Rollback: str{exc_val})') else: await self._session.flush() await self._session.commit() self._logger.debug('Commit') await self._session.close() @property def order_repository(self) -> IOrderRepository: if self._order_repository is None: self._order_repository = OrderRepository(session=self._session, logger=self._logger) return self._order_repository @property def payment_repository(self) -> IPaymentRepository: if self._payment_repository is None: self._payment_repository = PaymentRepository(session=self._session, logger=self._logger) return self._payment_repository @property def user_repository(self) -> IUserRepository: if self._user_repository is None: self._user_repository = UserRepository(session=self._session, logger=self._logger) return self._user_repository