dependency-injection-pattern 0.0.6__tar.gz → 0.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dependency_injection_pattern-0.0.6/src/dependency_injection_pattern.egg-info → dependency_injection_pattern-0.0.8}/PKG-INFO +127 -15
- dependency_injection_pattern-0.0.8/README.md +182 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/pyproject.toml +5 -4
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8/src/dependency_injection_pattern.egg-info}/PKG-INFO +127 -15
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/dependency_injection_pattern.egg-info/SOURCES.txt +1 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/dependency_injection_pattern.egg-info/requires.txt +2 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/__init__.py +5 -5
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/container.py +36 -31
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/default_scope.py +13 -11
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/factory_provide_exception.py +4 -1
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/implementation_exception.py +1 -0
- dependency_injection_pattern-0.0.8/src/di/core/exceptions/internal_exception.py +4 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/provide_exception.py +1 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factories/dependency.py +4 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factories/factory.py +16 -10
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factories/scoped_factory.py +3 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factories/singleton_factory.py +6 -4
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factories/transient_factory.py +3 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/factory.py +3 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/helpers.py +8 -13
- dependency_injection_pattern-0.0.8/src/di/core/log.py +4 -0
- dependency_injection_pattern-0.0.8/src/di/core/named_service.py +6 -0
- dependency_injection_pattern-0.0.8/src/di/core/protocols/factory.py +7 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/protocols/provider.py +1 -1
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/provider.py +7 -8
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/scope.py +3 -1
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/service_request.py +2 -2
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/exceptions.py +7 -7
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/tests/test_provider.py +20 -0
- dependency_injection_pattern-0.0.6/README.md +0 -71
- dependency_injection_pattern-0.0.6/src/di/core/log.py +0 -4
- dependency_injection_pattern-0.0.6/src/di/core/named_service.py +0 -3
- dependency_injection_pattern-0.0.6/src/di/core/protocols/factory.py +0 -7
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/LICENSE +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/setup.cfg +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/dependency_injection_pattern.egg-info/dependency_links.txt +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/dependency_injection_pattern.egg-info/top_level.txt +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/add_exception.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/container_sealed_error.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/exceptions/seal_exception.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/core/protocols/container.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/tests/test_container.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/tests/test_examples.py +0 -0
- {dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/tests/test_factory.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dependency-injection-pattern
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: Python implementation of the Dependency Injection pattern.
|
|
5
5
|
Author-email: Anders Madsen <anders.madsen@alphavue.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -14,22 +14,23 @@ Classifier: Intended Audience :: Developers
|
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
22
|
Classifier: Programming Language :: Python
|
|
22
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
24
25
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python:
|
|
26
|
+
Requires-Python: <3.16,>=3.11
|
|
26
27
|
Description-Content-Type: text/markdown
|
|
27
28
|
License-File: LICENSE
|
|
28
29
|
Requires-Dist: typing-utilities<0.2,>=0.1.0
|
|
29
30
|
Requires-Dist: runtime-reflection-lite<0.3,>=0.2.0
|
|
30
31
|
Provides-Extra: test
|
|
31
|
-
Requires-Dist: pytest>=
|
|
32
|
-
Requires-Dist: pytest-cov>=
|
|
32
|
+
Requires-Dist: pytest>=9.0; extra == "test"
|
|
33
|
+
Requires-Dist: pytest-cov>=7.0; extra == "test"
|
|
33
34
|
Dynamic: license-file
|
|
34
35
|
|
|
35
36
|
[](https://github.com/apmadsen/dependency-injection-pattern/actions/workflows/python-test.yml)
|
|
@@ -39,22 +40,133 @@ Dynamic: license-file
|
|
|
39
40
|

|
|
40
41
|
[](https://pepy.tech/projects/dependency-injection-pattern)
|
|
41
42
|
|
|
42
|
-
#
|
|
43
|
-
> A Python implementation of the Dependency Injection pattern.
|
|
43
|
+
# Dependency Injection Pattern (Python)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
A typed dependency injection framework for Python — focused on clarity, structure, and maintainability.
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
## 🚀 Why this exists
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
When a service is requested, the provider looks it up in the factory dictionary, which then gets or creates a fitting instance. Any parameters needed for instantiation is supplied (injected) by the provider.
|
|
49
|
+
As Python applications grow, managing dependencies becomes increasingly difficult:
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
- Hidden dependencies make systems harder to understand
|
|
52
|
+
- Tight coupling reduces flexibility
|
|
53
|
+
- Testing requires complex setup and mocking
|
|
54
|
+
- Structure becomes inconsistent across modules
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
Unlike many other ecosystems, Python lacks a widely adopted, structured approach to dependency injection.
|
|
57
|
+
|
|
58
|
+
👉 This project aims to introduce **clear, typed dependency management** to Python applications.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## ✨ Features
|
|
62
|
+
|
|
63
|
+
- 🧩 Strongly typed dependency injection
|
|
64
|
+
- 🧠 Explicit dependency definitions
|
|
65
|
+
- 🔄 Clear separation of concerns
|
|
66
|
+
- 🧪 Improved testability
|
|
67
|
+
- 🏗 Support for structured application architecture
|
|
68
|
+
- ⚡ Lightweight and Python-native design
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## 📦 Use cases
|
|
72
|
+
|
|
73
|
+
This library is particularly useful when building:
|
|
74
|
+
|
|
75
|
+
- Backend services
|
|
76
|
+
- Data engineering workflows
|
|
77
|
+
- ETL pipelines
|
|
78
|
+
- Modular applications
|
|
79
|
+
- Systems with complex dependency graphs
|
|
80
|
+
|
|
81
|
+
👉 Especially valuable in projects where maintainability and scalability matter.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
## 🏗 Design philosophy
|
|
85
|
+
|
|
86
|
+
This project is built around a few key principles:
|
|
87
|
+
|
|
88
|
+
### 1. Explicit over implicit
|
|
89
|
+
Dependencies should be visible and well-defined — not hidden in implementation details.
|
|
90
|
+
|
|
91
|
+
### 2. Type-driven structure
|
|
92
|
+
Type hints are used as a foundation for defining and resolving dependencies.
|
|
93
|
+
|
|
94
|
+
### 3. Maintainability over convenience
|
|
95
|
+
The goal is not to reduce lines of code — but to make systems easier to evolve.
|
|
96
|
+
|
|
97
|
+
### 4. Minimal abstraction
|
|
98
|
+
The framework avoids unnecessary complexity and stays close to Python’s core concepts.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## 🔗 What this enables
|
|
102
|
+
|
|
103
|
+
By introducing structured dependency injection, you get:
|
|
104
|
+
|
|
105
|
+
- Clear boundaries between components
|
|
106
|
+
- Easier reasoning about system design
|
|
107
|
+
- More predictable runtime behavior
|
|
108
|
+
- Improved ability to refactor safely
|
|
109
|
+
|
|
110
|
+
👉 This is especially powerful in larger systems where complexity grows over time.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## ⚖️ Trade-offs
|
|
114
|
+
|
|
115
|
+
| Focus ✅ | Not a goal ❌ |
|
|
116
|
+
|---------|--------------|
|
|
117
|
+
| Structured architecture | Magic-based auto-wiring |
|
|
118
|
+
| Type safety | Implicit dependency resolution |
|
|
119
|
+
| Clarity and control | Minimal configuration at all costs |
|
|
120
|
+
|
|
121
|
+
👉 This library prioritizes **explicit design over automation**.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## 🧠 Inspiration
|
|
125
|
+
|
|
126
|
+
Inspired by dependency injection patterns from ecosystems such as:
|
|
127
|
+
|
|
128
|
+
- C# / .NET (built-in DI container)
|
|
129
|
+
- Java (Spring, Guice)
|
|
130
|
+
|
|
131
|
+
But intentionally adapted to fit Python’s dynamic nature
|
|
132
|
+
without introducing heavy frameworks or unnecessary indirection.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
## 🎯 When to use
|
|
136
|
+
|
|
137
|
+
Use this library if you:
|
|
138
|
+
|
|
139
|
+
- Are building medium to large Python applications
|
|
140
|
+
- Want clearer separation between components
|
|
141
|
+
- Need better testability
|
|
142
|
+
- Prefer structured architecture over ad-hoc patterns
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
## 🚫 When not to use
|
|
146
|
+
|
|
147
|
+
This library may be unnecessary if:
|
|
148
|
+
|
|
149
|
+
- Your project is small or short-lived
|
|
150
|
+
- Dependency complexity is minimal
|
|
151
|
+
- Simplicity is more important than structure
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## 🔗 Related projects
|
|
155
|
+
|
|
156
|
+
Part of a broader focus on:
|
|
157
|
+
|
|
158
|
+
- Clean architecture
|
|
159
|
+
- Runtime abstractions
|
|
160
|
+
- Developer tooling in Python
|
|
161
|
+
|
|
162
|
+
👉 https://github.com/apmadsen
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
## 🤝 Contributing
|
|
167
|
+
|
|
168
|
+
Feedback, ideas, and contributions are welcome!
|
|
56
169
|
|
|
57
|
-
- Singleton services may not depend on scoped or transient services, as this would negate the "transient" or "scoped" part since a singleton service would keep a reference to it's dependencies indefinitely.
|
|
58
170
|
|
|
59
171
|
## Example:
|
|
60
172
|
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
[](https://github.com/apmadsen/dependency-injection-pattern/actions/workflows/python-test.yml)
|
|
2
|
+
[](https://github.com/apmadsen/dependency-injection-pattern/actions/workflows/python-test-coverage.yml)
|
|
3
|
+
[](https://github.com/apmadsen/dependency-injection-pattern/releases)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://pepy.tech/projects/dependency-injection-pattern)
|
|
7
|
+
|
|
8
|
+
# Dependency Injection Pattern (Python)
|
|
9
|
+
|
|
10
|
+
A typed dependency injection framework for Python — focused on clarity, structure, and maintainability.
|
|
11
|
+
|
|
12
|
+
## 🚀 Why this exists
|
|
13
|
+
|
|
14
|
+
As Python applications grow, managing dependencies becomes increasingly difficult:
|
|
15
|
+
|
|
16
|
+
- Hidden dependencies make systems harder to understand
|
|
17
|
+
- Tight coupling reduces flexibility
|
|
18
|
+
- Testing requires complex setup and mocking
|
|
19
|
+
- Structure becomes inconsistent across modules
|
|
20
|
+
|
|
21
|
+
Unlike many other ecosystems, Python lacks a widely adopted, structured approach to dependency injection.
|
|
22
|
+
|
|
23
|
+
👉 This project aims to introduce **clear, typed dependency management** to Python applications.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## ✨ Features
|
|
27
|
+
|
|
28
|
+
- 🧩 Strongly typed dependency injection
|
|
29
|
+
- 🧠 Explicit dependency definitions
|
|
30
|
+
- 🔄 Clear separation of concerns
|
|
31
|
+
- 🧪 Improved testability
|
|
32
|
+
- 🏗 Support for structured application architecture
|
|
33
|
+
- ⚡ Lightweight and Python-native design
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## 📦 Use cases
|
|
37
|
+
|
|
38
|
+
This library is particularly useful when building:
|
|
39
|
+
|
|
40
|
+
- Backend services
|
|
41
|
+
- Data engineering workflows
|
|
42
|
+
- ETL pipelines
|
|
43
|
+
- Modular applications
|
|
44
|
+
- Systems with complex dependency graphs
|
|
45
|
+
|
|
46
|
+
👉 Especially valuable in projects where maintainability and scalability matter.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## 🏗 Design philosophy
|
|
50
|
+
|
|
51
|
+
This project is built around a few key principles:
|
|
52
|
+
|
|
53
|
+
### 1. Explicit over implicit
|
|
54
|
+
Dependencies should be visible and well-defined — not hidden in implementation details.
|
|
55
|
+
|
|
56
|
+
### 2. Type-driven structure
|
|
57
|
+
Type hints are used as a foundation for defining and resolving dependencies.
|
|
58
|
+
|
|
59
|
+
### 3. Maintainability over convenience
|
|
60
|
+
The goal is not to reduce lines of code — but to make systems easier to evolve.
|
|
61
|
+
|
|
62
|
+
### 4. Minimal abstraction
|
|
63
|
+
The framework avoids unnecessary complexity and stays close to Python’s core concepts.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## 🔗 What this enables
|
|
67
|
+
|
|
68
|
+
By introducing structured dependency injection, you get:
|
|
69
|
+
|
|
70
|
+
- Clear boundaries between components
|
|
71
|
+
- Easier reasoning about system design
|
|
72
|
+
- More predictable runtime behavior
|
|
73
|
+
- Improved ability to refactor safely
|
|
74
|
+
|
|
75
|
+
👉 This is especially powerful in larger systems where complexity grows over time.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## ⚖️ Trade-offs
|
|
79
|
+
|
|
80
|
+
| Focus ✅ | Not a goal ❌ |
|
|
81
|
+
|---------|--------------|
|
|
82
|
+
| Structured architecture | Magic-based auto-wiring |
|
|
83
|
+
| Type safety | Implicit dependency resolution |
|
|
84
|
+
| Clarity and control | Minimal configuration at all costs |
|
|
85
|
+
|
|
86
|
+
👉 This library prioritizes **explicit design over automation**.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## 🧠 Inspiration
|
|
90
|
+
|
|
91
|
+
Inspired by dependency injection patterns from ecosystems such as:
|
|
92
|
+
|
|
93
|
+
- C# / .NET (built-in DI container)
|
|
94
|
+
- Java (Spring, Guice)
|
|
95
|
+
|
|
96
|
+
But intentionally adapted to fit Python’s dynamic nature
|
|
97
|
+
without introducing heavy frameworks or unnecessary indirection.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## 🎯 When to use
|
|
101
|
+
|
|
102
|
+
Use this library if you:
|
|
103
|
+
|
|
104
|
+
- Are building medium to large Python applications
|
|
105
|
+
- Want clearer separation between components
|
|
106
|
+
- Need better testability
|
|
107
|
+
- Prefer structured architecture over ad-hoc patterns
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
## 🚫 When not to use
|
|
111
|
+
|
|
112
|
+
This library may be unnecessary if:
|
|
113
|
+
|
|
114
|
+
- Your project is small or short-lived
|
|
115
|
+
- Dependency complexity is minimal
|
|
116
|
+
- Simplicity is more important than structure
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## 🔗 Related projects
|
|
120
|
+
|
|
121
|
+
Part of a broader focus on:
|
|
122
|
+
|
|
123
|
+
- Clean architecture
|
|
124
|
+
- Runtime abstractions
|
|
125
|
+
- Developer tooling in Python
|
|
126
|
+
|
|
127
|
+
👉 https://github.com/apmadsen
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## 🤝 Contributing
|
|
132
|
+
|
|
133
|
+
Feedback, ideas, and contributions are welcome!
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## Example:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from logging import Logger
|
|
140
|
+
from di import Container
|
|
141
|
+
|
|
142
|
+
def get_logger() -> Logger:
|
|
143
|
+
return Logger("app")
|
|
144
|
+
|
|
145
|
+
class Service1:
|
|
146
|
+
def get_value(self) -> str:
|
|
147
|
+
return "Some value"
|
|
148
|
+
|
|
149
|
+
class Service2:
|
|
150
|
+
def __init__(self, service1: Service1, log: Logger):
|
|
151
|
+
self.service1 = service1
|
|
152
|
+
self.log = log
|
|
153
|
+
|
|
154
|
+
def get_value(self) -> str:
|
|
155
|
+
self.log.debug("Someone requested value...")
|
|
156
|
+
return f"Service1 returned: {self.service1.get_value()}"
|
|
157
|
+
|
|
158
|
+
class Application:
|
|
159
|
+
def __init__(self, service2: Service2, log: Logger):
|
|
160
|
+
self.service2 = service2
|
|
161
|
+
log.info("Application starting")
|
|
162
|
+
|
|
163
|
+
def get_value(self) -> str:
|
|
164
|
+
return f"Service2 returned: {self.service2.get_value()}"
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
container = Container()
|
|
168
|
+
container.add_singleton(get_logger)
|
|
169
|
+
container.add_transient(Service1)
|
|
170
|
+
container.add_transient(Service2)
|
|
171
|
+
container.add_transient(Application)
|
|
172
|
+
|
|
173
|
+
provider = container.provider() # container is sealed beyond this point
|
|
174
|
+
|
|
175
|
+
app = provider.provide(Application)
|
|
176
|
+
|
|
177
|
+
value = app.get_value() # => "Service2 returned: Service1 returned: Some value"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Full documentation
|
|
181
|
+
|
|
182
|
+
[Go to documentation](https://github.com/apmadsen/dependency-injection-pattern/blob/main/docs/documentation.md)
|
|
@@ -18,10 +18,11 @@ classifiers = [
|
|
|
18
18
|
"Natural Language :: English",
|
|
19
19
|
"Programming Language :: Python :: 3 :: Only",
|
|
20
20
|
"Programming Language :: Python :: 3",
|
|
21
|
-
"Programming Language :: Python :: 3.10",
|
|
22
21
|
"Programming Language :: Python :: 3.11",
|
|
23
22
|
"Programming Language :: Python :: 3.12",
|
|
24
23
|
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
25
|
+
"Programming Language :: Python :: 3.15",
|
|
25
26
|
"Programming Language :: Python",
|
|
26
27
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
28
|
"Topic :: Software Development :: Libraries",
|
|
@@ -31,15 +32,15 @@ dependencies = [
|
|
|
31
32
|
"typing-utilities >= 0.1.0, < 0.2",
|
|
32
33
|
"runtime-reflection-lite >= 0.2.0, < 0.3"
|
|
33
34
|
]
|
|
34
|
-
requires-python = ">=3.
|
|
35
|
+
requires-python = ">= 3.11, < 3.16"
|
|
35
36
|
|
|
36
37
|
[project.urls]
|
|
37
38
|
repository = "https://github.com/apmadsen/dependency-injection-pattern"
|
|
38
39
|
|
|
39
40
|
[project.optional-dependencies]
|
|
40
41
|
test = [
|
|
41
|
-
"pytest>=
|
|
42
|
-
"pytest-cov>=
|
|
42
|
+
"pytest>=9.0",
|
|
43
|
+
"pytest-cov>=7.0",
|
|
43
44
|
]
|
|
44
45
|
|
|
45
46
|
[tool.setuptools-git-versioning]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dependency-injection-pattern
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: Python implementation of the Dependency Injection pattern.
|
|
5
5
|
Author-email: Anders Madsen <anders.madsen@alphavue.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -14,22 +14,23 @@ Classifier: Intended Audience :: Developers
|
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
22
|
Classifier: Programming Language :: Python
|
|
22
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
24
25
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python:
|
|
26
|
+
Requires-Python: <3.16,>=3.11
|
|
26
27
|
Description-Content-Type: text/markdown
|
|
27
28
|
License-File: LICENSE
|
|
28
29
|
Requires-Dist: typing-utilities<0.2,>=0.1.0
|
|
29
30
|
Requires-Dist: runtime-reflection-lite<0.3,>=0.2.0
|
|
30
31
|
Provides-Extra: test
|
|
31
|
-
Requires-Dist: pytest>=
|
|
32
|
-
Requires-Dist: pytest-cov>=
|
|
32
|
+
Requires-Dist: pytest>=9.0; extra == "test"
|
|
33
|
+
Requires-Dist: pytest-cov>=7.0; extra == "test"
|
|
33
34
|
Dynamic: license-file
|
|
34
35
|
|
|
35
36
|
[](https://github.com/apmadsen/dependency-injection-pattern/actions/workflows/python-test.yml)
|
|
@@ -39,22 +40,133 @@ Dynamic: license-file
|
|
|
39
40
|

|
|
40
41
|
[](https://pepy.tech/projects/dependency-injection-pattern)
|
|
41
42
|
|
|
42
|
-
#
|
|
43
|
-
> A Python implementation of the Dependency Injection pattern.
|
|
43
|
+
# Dependency Injection Pattern (Python)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
A typed dependency injection framework for Python — focused on clarity, structure, and maintainability.
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
## 🚀 Why this exists
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
When a service is requested, the provider looks it up in the factory dictionary, which then gets or creates a fitting instance. Any parameters needed for instantiation is supplied (injected) by the provider.
|
|
49
|
+
As Python applications grow, managing dependencies becomes increasingly difficult:
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
- Hidden dependencies make systems harder to understand
|
|
52
|
+
- Tight coupling reduces flexibility
|
|
53
|
+
- Testing requires complex setup and mocking
|
|
54
|
+
- Structure becomes inconsistent across modules
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
Unlike many other ecosystems, Python lacks a widely adopted, structured approach to dependency injection.
|
|
57
|
+
|
|
58
|
+
👉 This project aims to introduce **clear, typed dependency management** to Python applications.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## ✨ Features
|
|
62
|
+
|
|
63
|
+
- 🧩 Strongly typed dependency injection
|
|
64
|
+
- 🧠 Explicit dependency definitions
|
|
65
|
+
- 🔄 Clear separation of concerns
|
|
66
|
+
- 🧪 Improved testability
|
|
67
|
+
- 🏗 Support for structured application architecture
|
|
68
|
+
- ⚡ Lightweight and Python-native design
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## 📦 Use cases
|
|
72
|
+
|
|
73
|
+
This library is particularly useful when building:
|
|
74
|
+
|
|
75
|
+
- Backend services
|
|
76
|
+
- Data engineering workflows
|
|
77
|
+
- ETL pipelines
|
|
78
|
+
- Modular applications
|
|
79
|
+
- Systems with complex dependency graphs
|
|
80
|
+
|
|
81
|
+
👉 Especially valuable in projects where maintainability and scalability matter.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
## 🏗 Design philosophy
|
|
85
|
+
|
|
86
|
+
This project is built around a few key principles:
|
|
87
|
+
|
|
88
|
+
### 1. Explicit over implicit
|
|
89
|
+
Dependencies should be visible and well-defined — not hidden in implementation details.
|
|
90
|
+
|
|
91
|
+
### 2. Type-driven structure
|
|
92
|
+
Type hints are used as a foundation for defining and resolving dependencies.
|
|
93
|
+
|
|
94
|
+
### 3. Maintainability over convenience
|
|
95
|
+
The goal is not to reduce lines of code — but to make systems easier to evolve.
|
|
96
|
+
|
|
97
|
+
### 4. Minimal abstraction
|
|
98
|
+
The framework avoids unnecessary complexity and stays close to Python’s core concepts.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## 🔗 What this enables
|
|
102
|
+
|
|
103
|
+
By introducing structured dependency injection, you get:
|
|
104
|
+
|
|
105
|
+
- Clear boundaries between components
|
|
106
|
+
- Easier reasoning about system design
|
|
107
|
+
- More predictable runtime behavior
|
|
108
|
+
- Improved ability to refactor safely
|
|
109
|
+
|
|
110
|
+
👉 This is especially powerful in larger systems where complexity grows over time.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## ⚖️ Trade-offs
|
|
114
|
+
|
|
115
|
+
| Focus ✅ | Not a goal ❌ |
|
|
116
|
+
|---------|--------------|
|
|
117
|
+
| Structured architecture | Magic-based auto-wiring |
|
|
118
|
+
| Type safety | Implicit dependency resolution |
|
|
119
|
+
| Clarity and control | Minimal configuration at all costs |
|
|
120
|
+
|
|
121
|
+
👉 This library prioritizes **explicit design over automation**.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## 🧠 Inspiration
|
|
125
|
+
|
|
126
|
+
Inspired by dependency injection patterns from ecosystems such as:
|
|
127
|
+
|
|
128
|
+
- C# / .NET (built-in DI container)
|
|
129
|
+
- Java (Spring, Guice)
|
|
130
|
+
|
|
131
|
+
But intentionally adapted to fit Python’s dynamic nature
|
|
132
|
+
without introducing heavy frameworks or unnecessary indirection.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
## 🎯 When to use
|
|
136
|
+
|
|
137
|
+
Use this library if you:
|
|
138
|
+
|
|
139
|
+
- Are building medium to large Python applications
|
|
140
|
+
- Want clearer separation between components
|
|
141
|
+
- Need better testability
|
|
142
|
+
- Prefer structured architecture over ad-hoc patterns
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
## 🚫 When not to use
|
|
146
|
+
|
|
147
|
+
This library may be unnecessary if:
|
|
148
|
+
|
|
149
|
+
- Your project is small or short-lived
|
|
150
|
+
- Dependency complexity is minimal
|
|
151
|
+
- Simplicity is more important than structure
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## 🔗 Related projects
|
|
155
|
+
|
|
156
|
+
Part of a broader focus on:
|
|
157
|
+
|
|
158
|
+
- Clean architecture
|
|
159
|
+
- Runtime abstractions
|
|
160
|
+
- Developer tooling in Python
|
|
161
|
+
|
|
162
|
+
👉 https://github.com/apmadsen
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
## 🤝 Contributing
|
|
167
|
+
|
|
168
|
+
Feedback, ideas, and contributions are welcome!
|
|
56
169
|
|
|
57
|
-
- Singleton services may not depend on scoped or transient services, as this would negate the "transient" or "scoped" part since a singleton service would keep a reference to it's dependencies indefinitely.
|
|
58
170
|
|
|
59
171
|
## Example:
|
|
60
172
|
|
|
@@ -21,6 +21,7 @@ src/di/core/exceptions/add_exception.py
|
|
|
21
21
|
src/di/core/exceptions/container_sealed_error.py
|
|
22
22
|
src/di/core/exceptions/factory_provide_exception.py
|
|
23
23
|
src/di/core/exceptions/implementation_exception.py
|
|
24
|
+
src/di/core/exceptions/internal_exception.py
|
|
24
25
|
src/di/core/exceptions/provide_exception.py
|
|
25
26
|
src/di/core/exceptions/seal_exception.py
|
|
26
27
|
src/di/core/factories/dependency.py
|
{dependency_injection_pattern-0.0.6 → dependency_injection_pattern-0.0.8}/src/di/__init__.py
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from di.core.container import Container
|
|
2
|
-
from di.core.provider import Provider
|
|
3
|
-
from di.core.scope import Scope
|
|
4
2
|
from di.core.default_scope import DefaultScope
|
|
5
3
|
from di.core.factory import Factory
|
|
4
|
+
from di.core.provider import Provider
|
|
5
|
+
from di.core.scope import Scope
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
'Container',
|
|
9
|
-
'Provider',
|
|
10
|
-
'Scope',
|
|
11
9
|
'DefaultScope',
|
|
12
|
-
'Factory'
|
|
10
|
+
'Factory',
|
|
11
|
+
'Provider',
|
|
12
|
+
'Scope'
|
|
13
13
|
]
|