update decoupled-example with abstraction layer

This commit is contained in:
qingsong 2023-12-10 13:25:16 +08:00
parent cc2304e46e
commit 20339af52b
13 changed files with 112 additions and 14 deletions

View File

@ -55,6 +55,17 @@ file.
./ ./
├── example/ ├── example/
│ ├── abstraction
│ │ ├── __init__.py
│ │ ├── analytics
│ │ │ ├── __init__.py
│ │ │ └── services.py
│ │ ├── photo
│ │ │ ├── __init__.py
│ │ │ └── repositories.py
│ │ └── user
│ │ ├── __init__.py
│ │ └── repositories.py
│ ├── analytics/ │ ├── analytics/
│ │ ├── __init__.py │ │ ├── __init__.py
│ │ ├── containers.py │ │ ├── containers.py
@ -75,6 +86,26 @@ file.
├── config.ini ├── config.ini
└── requirements.txt └── requirements.txt
Abstraction
------------------
Listing of the ``example/abstraction/user/repositories.py``:
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/abstraction/user/repositories.py
:language: python
Listing of the ``example/abstraction/photo/repositories.py``:
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/abstraction/photo/repositories.py
:language: python
Listing of the ``example/abstraction/analytics/services.py``:
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/abstraction/analytics/services.py
:language: python
Package containers Package containers
------------------ ------------------

View File

@ -2,21 +2,22 @@
from dependency_injector.wiring import Provide, inject from dependency_injector.wiring import Provide, inject
from .user.repositories import UserRepository from .abstraction.user.repositories import UserRepositoryMeta
from .photo.repositories import PhotoRepository from .abstraction.photo.repositories import PhotoRepositoryMeta
from .analytics.services import AggregationService from .abstraction.analytics.services import AggregationServiceMeta
from .containers import ApplicationContainer from .containers import ApplicationContainer
@inject @inject
def main( def main(
user_repository: UserRepository = Provide[ user_repository: UserRepositoryMeta = Provide[
ApplicationContainer.user_package.user_repository ApplicationContainer.user_package.user_repository
], ],
photo_repository: PhotoRepository = Provide[ photo_repository: PhotoRepositoryMeta = Provide[
ApplicationContainer.photo_package.photo_repository ApplicationContainer.photo_package.photo_repository
], ],
aggregation_service: AggregationService = Provide[ aggregation_service: AggregationServiceMeta = Provide[
ApplicationContainer.analytics_package.aggregation_service ApplicationContainer.analytics_package.aggregation_service
], ],
) -> None: ) -> None:
@ -32,6 +33,8 @@ def main(
assert aggregation_service.photo_repository is photo_repository assert aggregation_service.photo_repository is photo_repository
print("Aggregate analytics from user and photo packages") print("Aggregate analytics from user and photo packages")
aggregation_service.call_user_photo()
if __name__ == "__main__": if __name__ == "__main__":
application = ApplicationContainer() application = ApplicationContainer()

View File

@ -0,0 +1 @@
"""abstraction package."""

View File

@ -0,0 +1 @@
"""abstraction analytics package."""

View File

@ -0,0 +1,19 @@
"""Analytics services module."""
import abc
from ..photo.repositories import PhotoRepositoryMeta
from ..user.repositories import UserRepositoryMeta
class AggregationServiceMeta(metaclass=abc.ABCMeta):
def __init__(self, user_repository: UserRepositoryMeta, photo_repository: PhotoRepositoryMeta):
self.user_repository: UserRepositoryMeta = user_repository
self.photo_repository: PhotoRepositoryMeta = photo_repository
@abc.abstractmethod
def call_user_photo(self):
"""Must be implemented in order to instantiate."""
pass

View File

@ -0,0 +1 @@
"""abstraction photo package."""

View File

@ -0,0 +1,11 @@
"""Photo repositories Meta module."""
import abc
class PhotoRepositoryMeta(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get_photos(self, user_id):
"""Must be implemented in order to instantiate."""
pass

View File

@ -0,0 +1 @@
"""abstraction user package."""

View File

@ -0,0 +1,12 @@
"""User repositories meta module."""
import abc
class UserRepositoryMeta(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get(self, id):
"""Must be implemented in order to instantiate."""
pass

View File

@ -4,11 +4,14 @@ from dependency_injector import containers, providers
from . import services from . import services
from ..abstraction.photo.repositories import PhotoRepositoryMeta
from ..abstraction.user.repositories import UserRepositoryMeta
class AnalyticsContainer(containers.DeclarativeContainer): class AnalyticsContainer(containers.DeclarativeContainer):
user_repository = providers.Dependency() user_repository: UserRepositoryMeta = providers.Dependency()
photo_repository = providers.Dependency() photo_repository: PhotoRepositoryMeta = providers.Dependency()
aggregation_service = providers.Singleton( aggregation_service = providers.Singleton(
services.AggregationService, services.AggregationService,

View File

@ -1,8 +1,18 @@
"""Analytics services module.""" """Analytics services module."""
class AggregationService: from ..abstraction.analytics.services import AggregationServiceMeta
from ..abstraction.photo.repositories import PhotoRepositoryMeta
from ..abstraction.user.repositories import UserRepositoryMeta
def __init__(self, user_repository, photo_repository):
self.user_repository = user_repository class AggregationService(AggregationServiceMeta):
self.photo_repository = photo_repository
def __init__(self, user_repository: UserRepositoryMeta, photo_repository: PhotoRepositoryMeta):
self.user_repository: UserRepositoryMeta = user_repository
self.photo_repository: PhotoRepositoryMeta = photo_repository
def call_user_photo(self):
user1 = self.user_repository.get(id=1)
user1_photos = self.photo_repository.get_photos(user1.id)
print(f"Retrieve user id={user1.id}, photos count={len(user1_photos)} from aggregation service.")

View File

@ -1,7 +1,10 @@
"""Photo repositories module.""" """Photo repositories module."""
class PhotoRepository: from ..abstraction.photo.repositories import PhotoRepositoryMeta
class PhotoRepository(PhotoRepositoryMeta):
def __init__(self, entity_factory, fs, db): def __init__(self, entity_factory, fs, db):
self.entity_factory = entity_factory self.entity_factory = entity_factory

View File

@ -1,7 +1,9 @@
"""User repositories module.""" """User repositories module."""
from ..abstraction.user.repositories import UserRepositoryMeta
class UserRepository:
class UserRepository(UserRepositoryMeta):
def __init__(self, entity_factory, db): def __init__(self, entity_factory, db):
self.entity_factory = entity_factory self.entity_factory = entity_factory