mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-22 17:47:02 +03:00
Update bundles example (#292)
* Fix dependency provider stub issue with required init arg * Refactor bundles example app * Rename bundles package * Rename bundles example container * Rename bundles mini app to decoupled packages * Move decoupled packages example to main examples * Fix a typo * Add meta
This commit is contained in:
parent
06bc0f1bac
commit
29f209d382
|
@ -1,74 +0,0 @@
|
||||||
Bundles mini application example
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
.. currentmodule:: dependency_injector.containers
|
|
||||||
|
|
||||||
"Bundles" is an example mini application that is intended to demonstrate the
|
|
||||||
power of dependency injection for creation of re-usable application components
|
|
||||||
("bundles") with 100% transparency of their dependencies.
|
|
||||||
|
|
||||||
Example application
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
"Bundles" mini application has next structure:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
bundles/
|
|
||||||
bundles/ <-- Bundles package
|
|
||||||
photos/ <-- Photos bundle
|
|
||||||
__init__.py <-- Photos bundle dependency injection container
|
|
||||||
entities.py
|
|
||||||
repositories.py
|
|
||||||
users/ <-- Users bundle
|
|
||||||
__init__.py <-- Users bundle dependency injection container
|
|
||||||
entities.py
|
|
||||||
repositories.py
|
|
||||||
run.py <-- Entrypoint
|
|
||||||
|
|
||||||
|
|
||||||
IoC containers
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Next two listings show :py:class:`DeclarativeContainer`'s for "users" and
|
|
||||||
"photos" bundles.
|
|
||||||
|
|
||||||
Listing of ``bundles/users/__init__.py``:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/miniapps/bundles/bundles/users/__init__.py
|
|
||||||
:language: python
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
- ``Users`` container has dependency on database.
|
|
||||||
|
|
||||||
Listing of ``bundles/photos/__init__.py``:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/miniapps/bundles/bundles/photos/__init__.py
|
|
||||||
:language: python
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
- ``Photos`` container has dependencies on database and file storage.
|
|
||||||
|
|
||||||
Run application
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Finally, both "bundles" are initialized by providing needed dependencies.
|
|
||||||
Initialization of dependencies happens right in the runtime, not earlier.
|
|
||||||
Generally, it means, that any part of any bundle could be overridden on the
|
|
||||||
fly.
|
|
||||||
|
|
||||||
Listing of ``run.py``:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/miniapps/bundles/run.py
|
|
||||||
:language: python
|
|
||||||
|
|
||||||
Links
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
+ `Dependency Injector <https://github.com/ets-labs/python-dependency-injector/>`_
|
|
||||||
+ `Full example sources <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/bundles>`_
|
|
||||||
|
|
||||||
|
|
||||||
.. disqus::
|
|
|
@ -8,14 +8,11 @@ Other examples
|
||||||
of inversion of control principle and powered by
|
of inversion of control principle and powered by
|
||||||
"Dependency Injector" framework.
|
"Dependency Injector" framework.
|
||||||
|
|
||||||
Current section of documentation is designed to provide several example mini
|
This sections contains assorted ``Dependency Injector`` examples.
|
||||||
applications that are built according to the inversion of control principle
|
|
||||||
and powered by *Dependency Injector* framework.
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
bundles_miniapp
|
|
||||||
use_cases_miniapp
|
use_cases_miniapp
|
||||||
password_hashing_miniapp
|
password_hashing_miniapp
|
||||||
chained_factories
|
chained_factories
|
||||||
|
|
130
docs/examples/decoupled-packages.rst
Normal file
130
docs/examples/decoupled-packages.rst
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
Decoupled packages example (multiple containers)
|
||||||
|
================================================
|
||||||
|
|
||||||
|
.. meta::
|
||||||
|
:keywords: Python,Dependency Injection,Inversion of Control,Container,Example,Application,
|
||||||
|
Framework,AWS,boto3,client
|
||||||
|
:description: This example shows how to use Dependency Injector to create Python decoupled packages.
|
||||||
|
To achieve a decoupling each package has a container with the components. When
|
||||||
|
a component needs a dependency from the outside of the package scope we use the
|
||||||
|
Dependency provider. The package container has no knowledge on where the
|
||||||
|
dependencies come from. It states a need that the dependencies must be provided.
|
||||||
|
This helps to decouple a package from the 3rd party dependencies and other
|
||||||
|
packages.
|
||||||
|
|
||||||
|
This example shows how to use ``Dependency Injector`` to create decoupled packages.
|
||||||
|
|
||||||
|
To achieve a decoupling each package has a container with the components. When a component needs a
|
||||||
|
dependency from the outside of the package scope we use the ``Dependency`` provider. The package
|
||||||
|
container has no knowledge on where the dependencies come from. It states a need that the
|
||||||
|
dependencies must be provided. This helps to decouple a package from the 3rd party dependencies
|
||||||
|
and other packages.
|
||||||
|
|
||||||
|
To wire the packages we use an application container. Application container has all 3rd party
|
||||||
|
dependencies and package containers. It wires the packages and dependencies to create a
|
||||||
|
complete application.
|
||||||
|
|
||||||
|
We build an example micro application that consists of 3 packages:
|
||||||
|
|
||||||
|
- ``user`` - a package with user domain logic, depends on a database
|
||||||
|
- ``photo`` - a package with photo domain logic, depends on a database and AWS S3
|
||||||
|
- ``analytics`` - a package with analytics domain logic, depends on the ``user`` and ``photo``
|
||||||
|
package components
|
||||||
|
|
||||||
|
.. image:: images/decoupled-packages.png
|
||||||
|
:width: 100%
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
Start from the scratch or jump to the section:
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:backlinks: none
|
||||||
|
|
||||||
|
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/decoupled-packages>`_.
|
||||||
|
|
||||||
|
Application structure
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Application consists of an ``example`` package, a configuration file and a ``requirements.txt``
|
||||||
|
file.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./
|
||||||
|
├── example/
|
||||||
|
│ ├── analytics/
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── containers.py
|
||||||
|
│ │ └── services.py
|
||||||
|
│ ├── photo/
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── containers.py
|
||||||
|
│ │ ├── entities.py
|
||||||
|
│ │ └── repositories.py
|
||||||
|
│ ├── user/
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── containers.py
|
||||||
|
│ │ ├── entities.py
|
||||||
|
│ │ └── repositories.py
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── __main__.py
|
||||||
|
│ └── containers.py
|
||||||
|
├── config.ini
|
||||||
|
└── requirements.txt
|
||||||
|
|
||||||
|
Package containers
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Listing of the ``example/user/containers.py``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/user/containers.py
|
||||||
|
:language: python
|
||||||
|
|
||||||
|
Listing of the ``example/photo/containers.py``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/photo/containers.py
|
||||||
|
:language: python
|
||||||
|
|
||||||
|
Listing of the ``example/analytics/containers.py``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/analytics/containers.py
|
||||||
|
:language: python
|
||||||
|
|
||||||
|
Application container
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Application container consists of all packages and 3rd party dependencies. Its role is to wire
|
||||||
|
everything together in a complete application.
|
||||||
|
|
||||||
|
Listing of the ``example/containers.py``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/containers.py
|
||||||
|
:language: python
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Package ``analytics`` has dependencies on the repositories from the ``user`` and
|
||||||
|
``photo`` packages. This is an example of how you can pass the dependencies from one package
|
||||||
|
to another.
|
||||||
|
|
||||||
|
Main module
|
||||||
|
-----------
|
||||||
|
Listing of the ``example/__main__.py``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/__main__.py
|
||||||
|
:language: python
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Listing of the ``config.ini``:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/miniapps/decoupled-packages/config.ini
|
||||||
|
:language: ini
|
||||||
|
|
||||||
|
Run the application
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/decoupled-packages>`_.
|
||||||
|
|
||||||
|
.. disqus::
|
BIN
docs/examples/images/decoupled-packages.png
Normal file
BIN
docs/examples/images/decoupled-packages.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
|
@ -12,5 +12,6 @@ Explore the examples to see the ``Dependency Injector`` in action.
|
||||||
|
|
||||||
application-single-container
|
application-single-container
|
||||||
application-multiple-containers
|
application-multiple-containers
|
||||||
|
decoupled-packages
|
||||||
|
|
||||||
.. disqus::
|
.. disqus::
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
Dependency Injector Bundles example
|
|
||||||
===================================
|
|
||||||
|
|
||||||
Instructions for running
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
python run.py
|
|
|
@ -1 +0,0 @@
|
||||||
"""Bundles package."""
|
|
|
@ -1,20 +0,0 @@
|
||||||
"""Photos bundle."""
|
|
||||||
|
|
||||||
from dependency_injector import containers
|
|
||||||
from dependency_injector import providers
|
|
||||||
|
|
||||||
from . import entities
|
|
||||||
from . import repositories
|
|
||||||
|
|
||||||
|
|
||||||
class Photos(containers.DeclarativeContainer):
|
|
||||||
"""Photos bundle container."""
|
|
||||||
|
|
||||||
database = providers.Dependency()
|
|
||||||
file_storage = providers.Dependency()
|
|
||||||
|
|
||||||
photo = providers.Factory(entities.Photo)
|
|
||||||
photo_repository = providers.Singleton(repositories.PhotoRepository,
|
|
||||||
object_factory=photo.provider,
|
|
||||||
fs=file_storage,
|
|
||||||
db=database)
|
|
|
@ -1,5 +0,0 @@
|
||||||
"""Photos bundle entities module."""
|
|
||||||
|
|
||||||
|
|
||||||
class Photo:
|
|
||||||
"""Photo entity."""
|
|
|
@ -1,11 +0,0 @@
|
||||||
"""Photos bundle entity repositories module."""
|
|
||||||
|
|
||||||
|
|
||||||
class PhotoRepository:
|
|
||||||
"""Photo entity repository."""
|
|
||||||
|
|
||||||
def __init__(self, object_factory, fs, db):
|
|
||||||
"""Initialize instance."""
|
|
||||||
self.object_factory = object_factory
|
|
||||||
self.fs = fs
|
|
||||||
self.db = db
|
|
|
@ -1,18 +0,0 @@
|
||||||
"""Users bundle."""
|
|
||||||
|
|
||||||
from dependency_injector import containers
|
|
||||||
from dependency_injector import providers
|
|
||||||
|
|
||||||
from . import entities
|
|
||||||
from . import repositories
|
|
||||||
|
|
||||||
|
|
||||||
class Users(containers.DeclarativeContainer):
|
|
||||||
"""Users bundle container."""
|
|
||||||
|
|
||||||
database = providers.Dependency()
|
|
||||||
|
|
||||||
user = providers.Factory(entities.User)
|
|
||||||
user_repository = providers.Singleton(repositories.UserRepository,
|
|
||||||
object_factory=user.provider,
|
|
||||||
db=database)
|
|
|
@ -1,9 +0,0 @@
|
||||||
"""Users bundle entities module."""
|
|
||||||
|
|
||||||
|
|
||||||
class User:
|
|
||||||
"""User entity."""
|
|
||||||
|
|
||||||
def __init__(self, id):
|
|
||||||
"""Initialize instance."""
|
|
||||||
self.id = id
|
|
|
@ -1,14 +0,0 @@
|
||||||
"""Users bundle entity repositories module."""
|
|
||||||
|
|
||||||
|
|
||||||
class UserRepository:
|
|
||||||
"""User entity repository."""
|
|
||||||
|
|
||||||
def __init__(self, object_factory, db):
|
|
||||||
"""Initialize instance."""
|
|
||||||
self.object_factory = object_factory
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
def get(self, id):
|
|
||||||
"""Return user entity with given identifier."""
|
|
||||||
return self.object_factory(id=id)
|
|
|
@ -1,40 +0,0 @@
|
||||||
"""Run 'Bundles' example application."""
|
|
||||||
|
|
||||||
import sqlite3
|
|
||||||
import boto3
|
|
||||||
|
|
||||||
from dependency_injector import containers
|
|
||||||
from dependency_injector import providers
|
|
||||||
|
|
||||||
from bundles.users import Users
|
|
||||||
from bundles.photos import Photos
|
|
||||||
|
|
||||||
|
|
||||||
class Core(containers.DeclarativeContainer):
|
|
||||||
"""Core container."""
|
|
||||||
|
|
||||||
config = providers.Configuration('config')
|
|
||||||
sqlite = providers.Singleton(sqlite3.connect, config.database.dsn)
|
|
||||||
s3 = providers.Singleton(
|
|
||||||
boto3.client, 's3',
|
|
||||||
aws_access_key_id=config.aws.access_key_id,
|
|
||||||
aws_secret_access_key=config.aws.secret_access_key)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# Initializing containers
|
|
||||||
core = Core(config={'database': {'dsn': ':memory:'},
|
|
||||||
'aws': {'access_key_id': 'KEY',
|
|
||||||
'secret_access_key': 'SECRET'}})
|
|
||||||
users = Users(database=core.sqlite)
|
|
||||||
photos = Photos(database=core.sqlite, file_storage=core.s3)
|
|
||||||
|
|
||||||
# Fetching few users
|
|
||||||
user_repository = users.user_repository()
|
|
||||||
user1 = user_repository.get(id=1)
|
|
||||||
user2 = user_repository.get(id=2)
|
|
||||||
|
|
||||||
# Making some checks
|
|
||||||
assert user1.id == 1
|
|
||||||
assert user2.id == 2
|
|
||||||
assert user_repository.db is core.sqlite()
|
|
29
examples/miniapps/decoupled-packages/README.rst
Normal file
29
examples/miniapps/decoupled-packages/README.rst
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
Decoupled packages example
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Create virtual env:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
python3 -m venv venv
|
||||||
|
. venv/bin/activate
|
||||||
|
|
||||||
|
Install requirements:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
python -m example
|
||||||
|
|
||||||
|
You should see:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Retrieve user id=1, photos count=5
|
||||||
|
Retrieve user id=2, photos count=10
|
||||||
|
Aggregate analytics from user and photo bundles
|
6
examples/miniapps/decoupled-packages/config.ini
Normal file
6
examples/miniapps/decoupled-packages/config.ini
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[database]
|
||||||
|
dsn=:memory:
|
||||||
|
|
||||||
|
[aws]
|
||||||
|
access_key_id=KEY
|
||||||
|
secret_access_key=SECRET
|
1
examples/miniapps/decoupled-packages/example/__init__.py
Normal file
1
examples/miniapps/decoupled-packages/example/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Top-level package."""
|
24
examples/miniapps/decoupled-packages/example/__main__.py
Normal file
24
examples/miniapps/decoupled-packages/example/__main__.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
"""Main module."""
|
||||||
|
|
||||||
|
from .containers import ApplicationContainer
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
application = ApplicationContainer()
|
||||||
|
application.config.from_ini('config.ini')
|
||||||
|
|
||||||
|
user_repository = application.user_package.user_repository()
|
||||||
|
photo_repository = application.photo_package.photo_repository()
|
||||||
|
|
||||||
|
user1 = user_repository.get(id=1)
|
||||||
|
user1_photos = photo_repository.get_photos(user1.id)
|
||||||
|
print(f'Retrieve user id={user1.id}, photos count={len(user1_photos)}')
|
||||||
|
|
||||||
|
user2 = user_repository.get(id=2)
|
||||||
|
user2_photos = photo_repository.get_photos(user2.id)
|
||||||
|
print(f'Retrieve user id={user2.id}, photos count={len(user2_photos)}')
|
||||||
|
|
||||||
|
aggregation_service = application.analytics_package.aggregation_service()
|
||||||
|
assert aggregation_service.user_repository is user_repository
|
||||||
|
assert aggregation_service.photo_repository is photo_repository
|
||||||
|
print('Aggregate analytics from user and photo packages')
|
|
@ -0,0 +1 @@
|
||||||
|
"""Analytics package."""
|
|
@ -0,0 +1,17 @@
|
||||||
|
"""Analytics containers module."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
from . import services
|
||||||
|
|
||||||
|
|
||||||
|
class AnalyticsContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
user_repository = providers.Dependency()
|
||||||
|
photo_repository = providers.Dependency()
|
||||||
|
|
||||||
|
aggregation_service = providers.Singleton(
|
||||||
|
services.AggregationService,
|
||||||
|
user_repository=user_repository,
|
||||||
|
photo_repository=photo_repository,
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
"""Analytics services module."""
|
||||||
|
|
||||||
|
|
||||||
|
class AggregationService:
|
||||||
|
|
||||||
|
def __init__(self, user_repository, photo_repository):
|
||||||
|
self.user_repository = user_repository
|
||||||
|
self.photo_repository = photo_repository
|
41
examples/miniapps/decoupled-packages/example/containers.py
Normal file
41
examples/miniapps/decoupled-packages/example/containers.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
"""Containers module."""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
from .user.containers import UserContainer
|
||||||
|
from .photo.containers import PhotoContainer
|
||||||
|
from .analytics.containers import AnalyticsContainer
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
sqlite = providers.Singleton(sqlite3.connect, config.database.dsn)
|
||||||
|
|
||||||
|
s3 = providers.Singleton(
|
||||||
|
boto3.client,
|
||||||
|
service_name='s3',
|
||||||
|
aws_access_key_id=config.aws.access_key_id,
|
||||||
|
aws_secret_access_key=config.aws.secret_access_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
user_package = providers.Container(
|
||||||
|
UserContainer,
|
||||||
|
database=sqlite,
|
||||||
|
)
|
||||||
|
|
||||||
|
photo_package = providers.Container(
|
||||||
|
PhotoContainer,
|
||||||
|
database=sqlite,
|
||||||
|
file_storage=s3,
|
||||||
|
)
|
||||||
|
|
||||||
|
analytics_package = providers.Container(
|
||||||
|
AnalyticsContainer,
|
||||||
|
user_repository=user_package.user_repository,
|
||||||
|
photo_repository=photo_package.photo_repository,
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
"""Photo package."""
|
|
@ -0,0 +1,20 @@
|
||||||
|
"""Photo containers module."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
from . import entities, repositories
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
database = providers.Dependency()
|
||||||
|
file_storage = providers.Dependency()
|
||||||
|
|
||||||
|
photo = providers.Factory(entities.Photo)
|
||||||
|
|
||||||
|
photo_repository = providers.Singleton(
|
||||||
|
repositories.PhotoRepository,
|
||||||
|
entity_factory=photo.provider,
|
||||||
|
fs=file_storage,
|
||||||
|
db=database,
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
"""Photo entities module."""
|
||||||
|
|
||||||
|
|
||||||
|
class Photo:
|
||||||
|
...
|
|
@ -0,0 +1,12 @@
|
||||||
|
"""Photo repositories module."""
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoRepository:
|
||||||
|
|
||||||
|
def __init__(self, entity_factory, fs, db):
|
||||||
|
self.entity_factory = entity_factory
|
||||||
|
self.fs = fs
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
def get_photos(self, user_id):
|
||||||
|
return [self.entity_factory() for _ in range(user_id*5)]
|
|
@ -0,0 +1 @@
|
||||||
|
"""User package."""
|
|
@ -0,0 +1,18 @@
|
||||||
|
"""User containers module."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
from . import entities, repositories
|
||||||
|
|
||||||
|
|
||||||
|
class UserContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
database = providers.Dependency()
|
||||||
|
|
||||||
|
user = providers.Factory(entities.User)
|
||||||
|
|
||||||
|
user_repository = providers.Singleton(
|
||||||
|
repositories.UserRepository,
|
||||||
|
entity_factory=user.provider,
|
||||||
|
db=database,
|
||||||
|
)
|
|
@ -0,0 +1,7 @@
|
||||||
|
"""User entities module."""
|
||||||
|
|
||||||
|
|
||||||
|
class User:
|
||||||
|
|
||||||
|
def __init__(self, id):
|
||||||
|
self.id = id
|
|
@ -0,0 +1,11 @@
|
||||||
|
"""User repositories module."""
|
||||||
|
|
||||||
|
|
||||||
|
class UserRepository:
|
||||||
|
|
||||||
|
def __init__(self, entity_factory, db):
|
||||||
|
self.entity_factory = entity_factory
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
def get(self, id):
|
||||||
|
return self.entity_factory(id=id)
|
2
examples/miniapps/decoupled-packages/requirements.txt
Normal file
2
examples/miniapps/decoupled-packages/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dependency-injector
|
||||||
|
boto3
|
|
@ -59,7 +59,7 @@ class Delegate(Provider):
|
||||||
|
|
||||||
|
|
||||||
class Dependency(Provider, Generic[T]):
|
class Dependency(Provider, Generic[T]):
|
||||||
def __init__(self, instance_of: Type[T]) -> None: ...
|
def __init__(self, instance_of: Type[T] = object) -> None: ...
|
||||||
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
||||||
@property
|
@property
|
||||||
def provided(self) -> ProvidedInstance: ...
|
def provided(self) -> ProvidedInstance: ...
|
||||||
|
|
Loading…
Reference in New Issue
Block a user