Skip to content

Commit f7f9ecb

Browse files
committed
Refactor dependency injection to use provider functions instead of container classes
1 parent a18870f commit f7f9ecb

File tree

2 files changed

+148
-9
lines changed

2 files changed

+148
-9
lines changed

conduit/core/dependencies.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@
44
from sqlalchemy.ext.asyncio import AsyncSession
55

66
from conduit.api.schemas.requests.article import ArticlesFilters, ArticlesPagination
7-
from conduit.core.container import container
7+
from conduit.core.providers import (
8+
get_article_service,
9+
get_auth_token_service,
10+
get_comment_service,
11+
get_db_session,
12+
get_profile_service,
13+
get_tag_service,
14+
get_user_auth_service,
15+
get_user_service,
16+
)
817
from conduit.core.security import HTTPTokenHeader
918
from conduit.domain.dtos.user import UserDTO
1019
from conduit.services.article import ArticleService
@@ -31,15 +40,15 @@
3140
JWTToken = Annotated[str, Depends(token_security)]
3241
JWTTokenOptional = Annotated[str, Depends(token_security_optional)]
3342

34-
DBSession = Annotated[AsyncSession, Depends(container.session)]
43+
DBSession = Annotated[AsyncSession, Depends(get_db_session)]
3544

36-
IAuthTokenService = Annotated[AuthTokenService, Depends(container.auth_token_service)]
37-
IUserAuthService = Annotated[UserAuthService, Depends(container.user_auth_service)]
38-
IUserService = Annotated[UserService, Depends(container.user_service)]
39-
IProfileService = Annotated[ProfileService, Depends(container.profile_service)]
40-
ITagService = Annotated[TagService, Depends(container.tag_service)]
41-
IArticleService = Annotated[ArticleService, Depends(container.article_service)]
42-
ICommentService = Annotated[CommentService, Depends(container.comment_service)]
45+
IAuthTokenService = Annotated[AuthTokenService, Depends(get_auth_token_service)]
46+
IUserAuthService = Annotated[UserAuthService, Depends(get_user_auth_service)]
47+
IUserService = Annotated[UserService, Depends(get_user_service)]
48+
IProfileService = Annotated[ProfileService, Depends(get_profile_service)]
49+
ITagService = Annotated[TagService, Depends(get_tag_service)]
50+
IArticleService = Annotated[ArticleService, Depends(get_article_service)]
51+
ICommentService = Annotated[CommentService, Depends(get_comment_service)]
4352

4453
DEFAULT_ARTICLES_LIMIT = 20
4554
DEFAULT_ARTICLES_OFFSET = 0

conduit/core/providers.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
from __future__ import annotations
2+
3+
from collections.abc import AsyncIterator
4+
from functools import lru_cache
5+
6+
from sqlalchemy.ext.asyncio import AsyncSession
7+
8+
from conduit.core.config import get_app_settings
9+
from conduit.core.container import container
10+
from conduit.domain.repositories.article import IArticleRepository
11+
from conduit.domain.repositories.article_tag import IArticleTagRepository
12+
from conduit.domain.repositories.comment import ICommentRepository
13+
from conduit.domain.repositories.favorite import IFavoriteRepository
14+
from conduit.domain.repositories.follower import IFollowerRepository
15+
from conduit.domain.repositories.tag import ITagRepository
16+
from conduit.domain.repositories.user import IUserRepository
17+
from conduit.domain.services.article import IArticleService
18+
from conduit.domain.services.auth import IUserAuthService
19+
from conduit.domain.services.auth_token import IAuthTokenService
20+
from conduit.domain.services.comment import ICommentService
21+
from conduit.domain.services.profile import IProfileService
22+
from conduit.domain.services.tag import ITagService
23+
from conduit.domain.services.user import IUserService
24+
from conduit.infrastructure.repositories.article import ArticleRepository
25+
from conduit.infrastructure.repositories.article_tag import ArticleTagRepository
26+
from conduit.infrastructure.repositories.comment import CommentRepository
27+
from conduit.infrastructure.repositories.favorite import FavoriteRepository
28+
from conduit.infrastructure.repositories.follower import FollowerRepository
29+
from conduit.infrastructure.repositories.tag import TagRepository
30+
from conduit.infrastructure.repositories.user import UserRepository
31+
from conduit.services.article import ArticleService
32+
from conduit.services.auth import UserAuthService
33+
from conduit.services.auth_token import AuthTokenService
34+
from conduit.services.comment import CommentService
35+
from conduit.services.profile import ProfileService
36+
from conduit.services.tag import TagService
37+
from conduit.services.user import UserService
38+
39+
40+
async def get_db_session() -> AsyncIterator[AsyncSession]:
41+
async for session in container.session():
42+
yield session
43+
44+
45+
@lru_cache
46+
def get_user_repo() -> IUserRepository:
47+
return UserRepository()
48+
49+
50+
@lru_cache
51+
def get_article_repo() -> IArticleRepository:
52+
return ArticleRepository()
53+
54+
55+
@lru_cache
56+
def get_article_tag_repo() -> IArticleTagRepository:
57+
return ArticleTagRepository()
58+
59+
60+
@lru_cache
61+
def get_comment_repo() -> ICommentRepository:
62+
return CommentRepository()
63+
64+
65+
@lru_cache
66+
def get_tag_repo() -> ITagRepository:
67+
return TagRepository()
68+
69+
70+
@lru_cache
71+
def get_favorite_repo() -> IFavoriteRepository:
72+
return FavoriteRepository()
73+
74+
75+
@lru_cache
76+
def get_follower_repo() -> IFollowerRepository:
77+
return FollowerRepository()
78+
79+
80+
@lru_cache
81+
def get_auth_token_service() -> IAuthTokenService:
82+
settings = get_app_settings()
83+
return AuthTokenService(
84+
secret_key=settings.jwt_secret_key,
85+
token_expiration_minutes=settings.jwt_token_expiration_minutes,
86+
algorithm=settings.jwt_algorithm,
87+
)
88+
89+
90+
@lru_cache
91+
def get_user_service() -> IUserService:
92+
return UserService(user_repo=get_user_repo())
93+
94+
95+
@lru_cache
96+
def get_profile_service() -> IProfileService:
97+
return ProfileService(
98+
user_service=get_user_service(), follower_repo=get_follower_repo()
99+
)
100+
101+
102+
@lru_cache
103+
def get_user_auth_service() -> IUserAuthService:
104+
return UserAuthService(
105+
user_service=get_user_service(), auth_token_service=get_auth_token_service()
106+
)
107+
108+
109+
@lru_cache
110+
def get_tag_service() -> ITagService:
111+
return TagService(tag_repo=get_tag_repo())
112+
113+
114+
@lru_cache
115+
def get_article_service() -> IArticleService:
116+
return ArticleService(
117+
article_repo=get_article_repo(),
118+
article_tag_repo=get_article_tag_repo(),
119+
favorite_repo=get_favorite_repo(),
120+
profile_service=get_profile_service(),
121+
)
122+
123+
124+
@lru_cache
125+
def get_comment_service() -> ICommentService:
126+
return CommentService(
127+
article_repo=get_article_repo(),
128+
comment_repo=get_comment_repo(),
129+
profile_service=get_profile_service(),
130+
)

0 commit comments

Comments
 (0)