44
55# py-dependency-injection
66
7- A dependency injection library for Python.
7+ A prototypical dependency injection library for Python.
88
99## Features
1010
11- - ** Dependency Container:** Manage and resolve object dependencies with a flexible and easy-to-use container.
12- - ** Dependency Scopes:** Define different scopes for dependencies, allowing for fine-grained control over their lifecycle.
13- - ** Constructor Injection:** Inject dependencies into constructors, promoting cleaner and more modular code.
14- - ** Method Injection:** Inject dependencies into methods, enabling more flexible dependency management within class instances.
15- - ** Tags:** Register and resolve dependencies using tags, facilitating flexible and dynamic dependency management.
16- - ** Factory Registration:** Register dependencies using factory functions for dynamic instantiation.
17- - ** Instance Registration:** Register existing instances as dependencies, providing more control over object creation.
18- - ** Python Compatibility:** Compatible with Python versions 3.7 to 3.12, ensuring broad compatibility with existing and future Python projects.
11+ - ** Scoped Registrations:** Define the lifetime of your dependencies as transient, scoped, or singleton.
12+ - ** Constructor Injection:** Automatically resolve and inject dependencies when creating instances.
13+ - ** Method Injection:** Inject dependencies into methods using a simple decorator.
14+ - ** Factory Functions:** Register factory functions, classes, or lambdas to create dependencies.
15+ - ** Instance Registration:** Register existing instances as dependencies.
16+ - ** Tag-Based Registration and Resolution:** Organize and resolve dependencies based on tags.
17+ - ** Multiple Containers:** Support for using multiple dependency containers.
1918
2019## Compatibility
2120
22- This library is compatible with the following Python versions:
21+ The library is compatible with the following Python versions:
2322
2423- 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
2524
@@ -29,138 +28,70 @@ This library is compatible with the following Python versions:
2928$ pip install py-dependency-injection
3029```
3130
32- ## Basic Usage
31+ ## Quick Start
3332
34- The following examples demonstrates how to use the library.
35-
36- ### Creating a Dependency Container
33+ Here's a quick example to get you started:
3734
3835``` python
39- # Get the default dependency container
40- dependency_container = DependencyContainer.get_instance()
41-
42- # Create additional named containers if needed
43- another_container = DependencyContainer.get_instance(name = " another_container" )
44- ```
36+ from dependency_injection.container import DependencyContainer
4537
46- ### Registering Dependencies with Scopes
47-
48- ``` python
49- # Register a transient dependency (a new instance every time)
50- dependency_container.register_transient(Connection, PostgresConnection)
38+ # Define an abstract Connection
39+ class Connection :
40+ pass
5141
52- # Register a scoped dependency (a new instance per scope)
53- dependency_container.register_scoped(Connection, PostgresConnection, scope_name = " http_request" )
42+ # Define a specific implementation of the Connection
43+ class PostgresConnection (Connection ):
44+ def connect (self ):
45+ print (" Connecting to PostgreSQL database..." )
5446
55- # Register a singleton dependency (a single instance for the container's lifetime)
56- dependency_container.register_singleton(Connection, PostgresConnection)
57- ```
58-
59- ### Using Constructor Arguments
60-
61- ``` python
62- # Register a dependency with constructor arguments
63- dependency_container.register_transient(
64- Connection,
65- PostgresConnection,
66- constructor_args = {" host" : " localhost" , " port" : 5432 }
67- )
68- ```
69-
70- ### Using Factory Functions
71-
72- ``` python
73- # Define a factory function
74- def create_connection (host : str , port : int ) -> Connection:
75- return PostgresConnection(host = host, port = port)
47+ # Define a repository that depends on some type of Connection
48+ class UserRepository :
49+ def __init__ (self , connection : Connection):
50+ self ._connection = connection
7651
77- # Register the factory function
78- dependency_container.register_factory(Connection, create_connection, factory_args = { " host " : " localhost " , " port " : 5432 } )
79- ```
52+ def fetch_users ( self ):
53+ self ._connection.connect( )
54+ print ( " Fetching users from the database... " )
8055
81- Besides functions, you can also use lambdas and class functions. Read more in the [ documentation] ( https://py-dependency-injection.readthedocs.io/en/latest/userguide.html#using-factory-functions ) .
56+ # Get an instance of the (default) DependencyContainer
57+ container = DependencyContainer.get_instance()
8258
83- ### Registering and Using Instances
59+ # Register the specific connection type as a singleton instance
60+ container.register_singleton(Connection, PostgresConnection)
8461
85- ``` python
86- # Create an instance
87- my_connection = PostgresConnection(host = " localhost" , port = 5432 )
62+ # Register UserRepository as a transient (new instance every time)
63+ container.register_transient(UserRepository)
8864
89- # Register the instance
90- dependency_container.register_instance(Connection, my_connection )
65+ # Resolve an instance of UserRepository, automatically injecting the required Connection
66+ user_repository = container.resolve(UserRepository )
9167
92- # Resolve the instance
93- resolved_connection = dependency_container.resolve(Connection)
94- print (resolved_connection.host) # Output: localhost
68+ # Use the resolved user_repository to perform an operation
69+ user_repository.find_all()
9570```
9671
97- ### Registering and Resolving with Tags
98-
99- ``` python
100- # Register dependencies with tags
101- dependency_container.register_transient(Connection, PostgresConnection, tags = {" Querying" , " Startable" })
102- dependency_container.register_scoped(BusConnection, KafkaBusConnection, tags = {" Publishing" , " Startable" })
103-
104- # Resolve dependencies by tags
105- startable_dependencies = dependency_container.resolve_all(tags = {" Startable" })
106- for dependency in startable_dependencies:
107- dependency.start()
108- ```
109-
110- ### Using Constructor Injection
111-
112- ``` python
113- class OrderRepository :
114- def __init__ (self , connection : Connection):
115- self .connection = connection
116-
117- # Register dependencies
118- dependency_container.register_transient(OrderRepository)
119- dependency_container.register_singleton(Connection, PostgresConnection)
120-
121- # Resolve the OrderRepository with injected dependencies
122- repository = dependency_container.resolve(OrderRepository)
123- print (repository.connection.__class__ .__name__ ) # Output: PostgresConnection
124- ```
72+ ## Documentation
12573
126- ### Using Method Injection
74+ For more advanced usage and examples, please visit our [ readthedocs ] ( https://py-dependency-injection.readthedocs.io/en/latest/ ) page.
12775
128- ``` python
129- class OrderController :
130- @ staticmethod
131- @inject ()
132- def place_order (order : Order, repository : OrderRepository):
133- order.status = " placed"
134- repository.save(order)
135-
136- # Register the dependency
137- dependency_container.register_transient(OrderRepository)
138- dependency_container.register_singleton(Connection, PostgresConnection)
139-
140- # Use method injection to inject the dependency
141- my_order = Order.create()
142- OrderController.place_order(order = my_order) # The repository instance will be automatically injected
143- ```
76+ ## License
14477
145- You can also specify container and scope using the decorator arguments ` container_name ` and ` scope_name ` .
78+ ` py-dependency-injection ` is released under the GPL 3 license. See [ LICENSE ] ( LICENSE ) for more details .
14679
147- ## Documentation
80+ ## Source Code
14881
149- For the latest documentation, visit [ readthedocs ] ( https://py-dependency-injection.readthedocs.io/en/latest/ ) .
82+ You can find the source code for ` py-dependency-injection ` on [ GitHub ] ( https://github.com/runemalm/ py-dependency-injection ) .
15083
151- ## Contribution
84+ ## Release Notes
15285
153- To contribute, create a pull request on the develop branch following the [ git flow ] ( https://nvie .com/posts/a-successful-git-branching-model/ ) branching model.
86+ ### [ 1.0.0-alpha.8 ] ( https://github .com/runemalm/py-dependency-injection/releases/tag/v1.0.0-alpha.8 ) (2024-06-07)
15487
155- ## Release Notes
88+ - Bug Fix: Fixed an issue in the dependency resolution logic where registered constructor arguments were not properly merged with automatically injected dependencies. This ensures that constructor arguments specified during registration are correctly combined with dependencies resolved by the container.
15689
15790### [ 1.0.0-alpha.7] ( https://github.com/runemalm/py-dependency-injection/releases/tag/v1.0.0-alpha.7 ) (2024-03-24)
15891
15992- Documentation Update: Updated the documentation to provide clearer instructions and more comprehensive examples.
16093- Preparing for Beta Release: Made necessary adjustments and refinements in preparation for the upcoming first beta release.
16194
162- This release focuses on enhancing the documentation and making final preparations for the transition to the beta phase. If you have any more updates or need further assistance, feel free to reach out!
163-
16495### [ 1.0.0-alpha.6] ( https://github.com/runemalm/py-dependency-injection/releases/tag/v1.0.0-alpha.6 ) (2024-03-23)
16596
16697- Factory Registration: Added support for registering dependencies using factory functions for dynamic instantiation.
0 commit comments