"""Dishka providers for dependency injection.""" from typing import AsyncGenerator from dishka import Provider, Scope, provide from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession from app.application import ( CreatePostUseCase, DeletePostUseCase, GetPostUseCase, ListPostsUseCase, PublishPostUseCase, UpdatePostUseCase, ) from app.application.interfaces import TransactionManager from app.domain.repositories import PostRepository from app.infrastructure.database.connection import AsyncSessionLocal, engine from app.infrastructure.repositories.post import SQLAlchemyPostRepository class DatabaseProvider(Provider): """Provider for database-related dependencies.""" @provide(scope=Scope.APP) def get_engine(self) -> AsyncEngine: """Provide SQLAlchemy engine.""" return engine @provide(scope=Scope.REQUEST) async def get_session(self) -> AsyncGenerator[AsyncSession, None]: """Provide database session per request.""" async with AsyncSessionLocal() as session: try: yield session finally: await session.close() class RepositoryProvider(Provider): """Provider for repository implementations.""" @provide(scope=Scope.REQUEST) def get_post_repository(self, session: AsyncSession) -> PostRepository: """Provide PostRepository implementation.""" return SQLAlchemyPostRepository(session) class TransactionManagerProvider(Provider): """Provider for transaction manager.""" @provide(scope=Scope.REQUEST) def get_transaction_manager(self, session: AsyncSession) -> TransactionManager: """Provide TransactionManager implementation.""" from app.infrastructure.di.transaction_manager import SessionTransactionManager return SessionTransactionManager(session) class UseCaseProvider(Provider): """Provider for use cases.""" @provide(scope=Scope.REQUEST) def get_create_post_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> CreatePostUseCase: """Provide CreatePostUseCase.""" return CreatePostUseCase( post_repo=post_repo, tx_manager=tx_manager, ) @provide(scope=Scope.REQUEST) def get_get_post_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> GetPostUseCase: """Provide GetPostUseCase.""" return GetPostUseCase( post_repo=post_repo, tx_manager=tx_manager, ) @provide(scope=Scope.REQUEST) def get_update_post_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> UpdatePostUseCase: """Provide UpdatePostUseCase.""" return UpdatePostUseCase( post_repo=post_repo, tx_manager=tx_manager, ) @provide(scope=Scope.REQUEST) def get_delete_post_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> DeletePostUseCase: """Provide DeletePostUseCase.""" return DeletePostUseCase( post_repo=post_repo, tx_manager=tx_manager, ) @provide(scope=Scope.REQUEST) def get_list_posts_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> ListPostsUseCase: """Provide ListPostsUseCase.""" return ListPostsUseCase( post_repo=post_repo, tx_manager=tx_manager, ) @provide(scope=Scope.REQUEST) def get_publish_post_use_case( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> PublishPostUseCase: """Provide PublishPostUseCase.""" return PublishPostUseCase( post_repo=post_repo, tx_manager=tx_manager, )