0
# Container Management
1
2
Containers organize providers into cohesive units and manage the dependency graph. They provide functionality for provider registration, dependency wiring, resource lifecycle management, and configuration loading.
3
4
## Capabilities
5
6
### Base Container Class
7
8
Foundation container class with core dependency management functionality.
9
10
```python { .api }
11
class Container:
12
"""Base container class with provider management and dependency wiring."""
13
def __init__(self): ...
14
def __setattr__(self, name, value): ...
15
def __getattr__(self, name): ...
16
17
# Provider management
18
def set_providers(self, **providers): ...
19
def set_provider(self, name, provider): ...
20
21
# Container overriding
22
def override(self, overriding): ...
23
def reset_override(self): ...
24
25
# Dependency wiring
26
def wire(self, modules=None, packages=None, from_package=None): ...
27
def unwire(self): ...
28
29
# Resource lifecycle
30
def init_resources(self): ...
31
def shutdown_resources(self): ...
32
33
# Configuration loading
34
def load_config(self): ...
35
def from_schema(self, schema): ...
36
def from_yaml_schema(self, filepath, loader=None): ...
37
def from_json_schema(self, filepath): ...
38
39
# Singleton management
40
def reset_singletons(self): ...
41
42
# Dependency validation
43
def check_dependencies(self): ...
44
45
# Provider traversal
46
def traverse(self, types=None): ...
47
```
48
49
### Dynamic Container
50
51
Runtime container with dynamic provider registration capabilities.
52
53
```python { .api }
54
class DynamicContainer(Container):
55
"""Runtime container with dynamic provider registration."""
56
```
57
58
Usage example:
59
60
```python
61
from dependency_injector import containers, providers
62
63
# Create dynamic container
64
container = containers.DynamicContainer()
65
66
# Add providers dynamically
67
container.set_providers(
68
database=providers.Singleton(Database, host="localhost"),
69
user_service=providers.Factory(UserService, database=container.database)
70
)
71
72
# Wire dependencies
73
container.wire(modules=[__name__])
74
```
75
76
### Declarative Container
77
78
Class-based container definition with compile-time provider declarations.
79
80
```python { .api }
81
class DeclarativeContainer(Container):
82
"""Class-based declarative container definition."""
83
def __init__(self, **overriding_providers): ...
84
85
@classmethod
86
def override(cls, overriding): ...
87
88
@classmethod
89
def override_providers(cls, **overriding_providers): ...
90
91
@classmethod
92
def reset_last_overriding(cls): ...
93
94
@classmethod
95
def reset_override(cls): ...
96
```
97
98
Usage example:
99
100
```python
101
from dependency_injector import containers, providers
102
103
class ApplicationContainer(containers.DeclarativeContainer):
104
# Configuration
105
config = providers.Configuration()
106
107
# Database
108
database = providers.Singleton(
109
Database,
110
host=config.database.host,
111
port=config.database.port,
112
username=config.database.username,
113
password=config.database.password,
114
)
115
116
# Services
117
user_repository = providers.Factory(
118
UserRepository,
119
database=database,
120
)
121
122
user_service = providers.Factory(
123
UserService,
124
repository=user_repository,
125
)
126
127
# Resources
128
redis_pool = providers.Resource(
129
RedisResource,
130
host=config.redis.host,
131
port=config.redis.port,
132
)
133
134
# Usage
135
container = ApplicationContainer()
136
container.config.from_yaml("config.yaml")
137
container.wire(modules=[__name__])
138
```
139
140
### Wiring Configuration
141
142
Configuration class for specifying wiring behavior and target modules.
143
144
```python { .api }
145
class WiringConfiguration:
146
"""Configuration for automatic dependency wiring."""
147
def __init__(
148
self,
149
modules=None,
150
packages=None,
151
from_package=None,
152
auto_wire=True,
153
keep_cache=False
154
): ...
155
```
156
157
Usage example:
158
159
```python
160
# Configure automatic wiring
161
class Container(containers.DeclarativeContainer):
162
wiring_config = containers.WiringConfiguration(
163
modules=["myapp.handlers", "myapp.services"],
164
packages=["myapp.web"],
165
auto_wire=True
166
)
167
168
# Providers...
169
```
170
171
### Container Overriding
172
173
Mechanisms for overriding containers and providers for testing and environment-specific configuration.
174
175
#### Container-Level Overriding
176
177
```python
178
# Base container
179
class BaseContainer(containers.DeclarativeContainer):
180
database = providers.Singleton(Database, host="localhost")
181
service = providers.Factory(Service, database=database)
182
183
# Test container with overrides
184
class TestContainer(containers.DeclarativeContainer):
185
database = providers.Singleton(MockDatabase)
186
187
# Override entire container
188
container = BaseContainer()
189
container.override(TestContainer)
190
```
191
192
#### Provider-Level Overriding
193
194
```python
195
# Override specific providers
196
container = ApplicationContainer()
197
with container.override_providers(
198
database=providers.Singleton(TestDatabase),
199
user_service=providers.Singleton(MockUserService)
200
):
201
# Use container with overridden providers
202
service = container.user_service()
203
```
204
205
### Resource Lifecycle Management
206
207
Containers automatically manage resource initialization and cleanup.
208
209
```python
210
# Initialize all resources in container
211
await container.init_resources()
212
213
# Shutdown all resources
214
await container.shutdown_resources()
215
216
# Context manager for resource lifecycle
217
async with container:
218
# Container resources are initialized
219
service = container.user_service()
220
result = await service.process()
221
# Resources are automatically shut down
222
```
223
224
### Configuration Integration
225
226
Containers can load configuration from multiple sources and formats.
227
228
```python
229
class Container(containers.DeclarativeContainer):
230
config = providers.Configuration()
231
232
# Load configuration
233
container = Container()
234
235
# From YAML file
236
container.config.from_yaml("config.yaml")
237
238
# From environment variables
239
container.config.database.host.from_env("DB_HOST", default="localhost")
240
container.config.database.port.from_env("DB_PORT", as_=int, default=5432)
241
242
# From dictionary
243
container.config.from_dict({
244
"database": {"url": "postgresql://localhost/mydb"},
245
"redis": {"host": "localhost", "port": 6379}
246
})
247
248
# From JSON schema
249
container.from_json_schema("schema.json")
250
```
251
252
### Dependency Validation
253
254
Containers can validate dependency graphs and detect circular dependencies.
255
256
```python
257
# Check for dependency issues
258
try:
259
container.check_dependencies()
260
except Exception as e:
261
print(f"Dependency error: {e}")
262
```
263
264
### Provider Traversal
265
266
Traverse and inspect the provider graph within containers.
267
268
```python
269
# Find all singleton providers
270
singletons = list(container.traverse(types=[providers.Singleton]))
271
272
# Find all resource providers
273
resources = list(container.traverse(types=[providers.Resource]))
274
275
# Custom traversal
276
for provider in container.traverse():
277
print(f"Provider: {provider}")
278
```
279
280
## Context Managers
281
282
Context managers for scoped operations and resource management.
283
284
```python { .api }
285
class ProvidersOverridingContext:
286
"""Context manager for provider overriding."""
287
def __enter__(self): ...
288
def __exit__(self, *exc_info): ...
289
290
class SingletonResetContext:
291
"""Context manager for singleton reset."""
292
def __enter__(self): ...
293
def __exit__(self, *exc_info): ...
294
```
295
296
Usage example:
297
298
```python
299
# Temporary provider overriding
300
with container.override_providers(
301
database=providers.Singleton(TestDatabase)
302
):
303
# Use overridden providers
304
pass
305
306
# Temporary singleton reset
307
with container.reset_singletons():
308
# Fresh singleton instances
309
pass
310
```
311
312
## Utility Functions
313
314
Helper functions for working with containers.
315
316
```python { .api }
317
def override(container):
318
"""Decorator for container overriding."""
319
320
def copy(container):
321
"""Decorator for container copying."""
322
323
def is_container(instance) -> bool:
324
"""Check if object is a container."""
325
```
326
327
Usage example:
328
329
```python
330
# Container override decorator
331
@containers.override(BaseContainer)
332
class TestContainer(containers.DeclarativeContainer):
333
database = providers.Singleton(MockDatabase)
334
335
# Container copy decorator
336
@containers.copy(BaseContainer)
337
class DevelopmentContainer(containers.DeclarativeContainer):
338
# Inherits all providers from BaseContainer
339
# Can add or override specific providers
340
debug = providers.Object(True)
341
```