or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-system.mdcontainer-management.mdframework-integrations.mdindex.mdprovider-system.mdscope-lifecycle.mdtype-markers.mdvalidation-configuration.md

container-management.mddocs/

0

# Container Management

1

2

Core container functionality for creating, configuring, and managing dependency injection containers. Containers handle dependency creation, caching, lifecycle management, and scope transitions.

3

4

## Capabilities

5

6

### Container Creation

7

8

Factory functions for creating dependency injection containers with provider registration and configuration options.

9

10

```python { .api }

11

def make_container(

12

*providers: BaseProvider,

13

scopes: type[BaseScope] = Scope,

14

context: dict[Any, Any] | None = None,

15

lock_factory: Callable[[], Any] = Lock,

16

skip_validation: bool = False,

17

start_scope: BaseScope | None = None,

18

validation_settings: ValidationSettings = DEFAULT_VALIDATION

19

) -> Container:

20

"""

21

Create a synchronous dependency injection container.

22

23

Parameters:

24

- providers: Provider instances containing dependency definitions

25

- scopes: Scope hierarchy class (default: Scope)

26

- context: Initial context values (deprecated)

27

- lock_factory: Factory for creating thread locks

28

- skip_validation: Skip dependency graph validation

29

- start_scope: Initial scope to enter

30

- validation_settings: Validation configuration

31

32

Returns:

33

Container instance ready for dependency resolution

34

"""

35

36

def make_async_container(

37

*providers: BaseProvider,

38

scopes: type[BaseScope] = Scope,

39

context: dict[Any, Any] | None = None,

40

lock_factory: Callable[[], AbstractAsyncContextManager[Any]] | None = Lock,

41

skip_validation: bool = False,

42

start_scope: BaseScope | None = None,

43

validation_settings: ValidationSettings = DEFAULT_VALIDATION

44

) -> AsyncContainer:

45

"""

46

Create an asynchronous dependency injection container.

47

48

Parameters:

49

- providers: Provider instances containing dependency definitions

50

- scopes: Scope hierarchy class (default: Scope)

51

- context: Initial context values (deprecated)

52

- lock_factory: Factory for creating async context manager locks

53

- skip_validation: Skip dependency graph validation

54

- start_scope: Initial scope to enter

55

- validation_settings: Validation configuration

56

57

Returns:

58

AsyncContainer instance ready for async dependency resolution

59

"""

60

```

61

62

**Usage Example:**

63

64

```python

65

from dishka import make_container, Provider, Scope

66

67

# Create providers

68

provider1 = Provider()

69

provider2 = Provider(scope=Scope.APP)

70

71

# Create container

72

container = make_container(

73

provider1,

74

provider2,

75

skip_validation=False,

76

start_scope=Scope.APP

77

)

78

```

79

80

### Synchronous Container

81

82

Main container class for synchronous dependency injection with lifecycle management and scope handling.

83

84

```python { .api }

85

class Container:

86

def __init__(

87

self,

88

registry: Registry,

89

*child_registries: Registry,

90

parent_container: Container | None = None,

91

context: dict[Any, Any] | None = None,

92

lock_factory: Callable[[], Any] = Lock,

93

close_parent: bool = False

94

): ...

95

96

def get(self, dependency_type: type[T], component: str = DEFAULT_COMPONENT) -> T:

97

"""

98

Resolve a dependency by type and optional component.

99

100

Parameters:

101

- dependency_type: The type to resolve

102

- component: Component identifier for isolation (default: "")

103

104

Returns:

105

Instance of the requested type

106

107

Raises:

108

- NoFactoryError: No factory found for the dependency

109

- DependencyCycleError: Circular dependency detected

110

"""

111

112

def __call__(

113

self,

114

context: dict[Any, Any] | None = None,

115

lock_factory: Callable[[], Any] | None = None,

116

scope: BaseScope | None = None

117

) -> ContextWrapper:

118

"""

119

Enter a child scope, returning a context manager.

120

121

Parameters:

122

- context: Additional context values (deprecated)

123

- lock_factory: Lock factory for the child container

124

- scope: Specific scope to enter (default: next in hierarchy)

125

126

Returns:

127

ContextWrapper that provides access to child container

128

"""

129

130

def close(self, exception: BaseException | None = None) -> None:

131

"""

132

Close the container and clean up resources.

133

134

Parameters:

135

- exception: Exception that caused the close (for cleanup context)

136

"""

137

138

@property

139

def scope(self) -> BaseScope:

140

"""Current scope of the container"""

141

142

@property

143

def context(self) -> MutableMapping[DependencyKey, Any]:

144

"""Context mapping (deprecated, use from_context instead)"""

145

```

146

147

**Usage Example:**

148

149

```python

150

# Get dependencies

151

client = container.get(SomeClient) # APP-scoped dependency

152

client2 = container.get(SomeClient) # Same instance

153

154

# Enter child scope

155

with container() as request_container:

156

service = request_container.get(Service) # REQUEST-scoped

157

service2 = request_container.get(Service) # Same instance in this scope

158

# Automatically closed when exiting context

159

160

# Clean up

161

container.close()

162

```

163

164

### Asynchronous Container

165

166

Asynchronous container class providing the same functionality as Container but with async/await support.

167

168

```python { .api }

169

class AsyncContainer:

170

def __init__(

171

self,

172

registry: Registry,

173

*child_registries: Registry,

174

parent_container: AsyncContainer | None = None,

175

context: dict[Any, Any] | None = None,

176

lock_factory: Callable[[], Any] = Lock,

177

close_parent: bool = False

178

): ...

179

180

async def get(self, dependency_type: type[T], component: str = DEFAULT_COMPONENT) -> T:

181

"""

182

Asynchronously resolve a dependency by type and optional component.

183

184

Parameters:

185

- dependency_type: The type to resolve

186

- component: Component identifier for isolation (default: "")

187

188

Returns:

189

Instance of the requested type

190

191

Raises:

192

- NoFactoryError: No factory found for the dependency

193

- DependencyCycleError: Circular dependency detected

194

"""

195

196

def __call__(

197

self,

198

context: dict[Any, Any] | None = None,

199

lock_factory: Callable[[], Any] | None = None,

200

scope: BaseScope | None = None

201

) -> AsyncContextWrapper:

202

"""

203

Enter a child scope, returning an async context manager.

204

205

Parameters:

206

- context: Additional context values (deprecated)

207

- lock_factory: Lock factory for the child container

208

- scope: Specific scope to enter (default: next in hierarchy)

209

210

Returns:

211

AsyncContextWrapper that provides access to child container

212

"""

213

214

async def close(self, exception: BaseException | None = None) -> None:

215

"""

216

Asynchronously close the container and clean up resources.

217

218

Parameters:

219

- exception: Exception that caused the close (for cleanup context)

220

"""

221

222

@property

223

def scope(self) -> BaseScope:

224

"""Current scope of the container"""

225

226

@property

227

def context(self) -> MutableMapping[DependencyKey, Any]:

228

"""Context mapping (deprecated, use from_context instead)"""

229

```

230

231

**Usage Example:**

232

233

```python

234

import asyncio

235

from dishka import make_async_container

236

237

async def main():

238

# Create async container

239

container = make_async_container(provider)

240

241

# Get dependencies

242

client = await container.get(SomeClient)

243

244

# Enter child scope

245

async with container() as request_container:

246

service = await request_container.get(Service)

247

# Use service

248

# Automatically closed when exiting context

249

250

# Clean up

251

await container.close()

252

253

asyncio.run(main())

254

```

255

256

### Context Management

257

258

The context wrapper classes manage scope transitions and provide clean resource management.

259

260

```python { .api }

261

class ContextWrapper:

262

"""Context manager for synchronous container scope transitions"""

263

def __enter__(self) -> Container: ...

264

def __exit__(self, exc_type, exc_val, exc_tb) -> None: ...

265

266

class AsyncContextWrapper:

267

"""Async context manager for asynchronous container scope transitions"""

268

async def __aenter__(self) -> AsyncContainer: ...

269

async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: ...

270

```

271

272

### Error Handling

273

274

Common exceptions that may be raised during container operations:

275

276

```python { .api }

277

class DishkaError(Exception):

278

"""Base exception class for all Dishka-related errors"""

279

280

class NoFactoryError(DishkaError):

281

"""

282

Raised when no factory is found for a requested dependency.

283

284

Attributes:

285

- requested: DependencyKey for the missing dependency

286

- path: Sequence of dependencies that led to this request

287

"""

288

289

class CycleDependenciesError(DishkaError):

290

"""

291

Raised when a circular dependency is detected in the dependency graph.

292

293

Attributes:

294

- path: Sequence of dependencies forming the cycle

295

"""

296

297

class NoChildScopesError(DishkaError):

298

"""Raised when trying to enter a child scope but none are available"""

299

300

class ChildScopeNotFoundError(DishkaError):

301

"""

302

Raised when a specific child scope cannot be found.

303

304

Attributes:

305

- child_scope: The scope that was requested

306

- current_scope: The current container scope

307

"""

308

309

class ExitError(DishkaError):

310

"""Raised when an error occurs during container exit/cleanup"""

311

312

class NoContextValueError(DishkaError):

313

"""Raised when a required context value is not found"""

314

315

class InvalidGraphError(DishkaError):

316

"""Raised when the dependency graph is invalid or malformed"""

317

318

class UnsupportedFactoryError(DishkaError):

319

"""Raised when a factory type is not supported by the container"""

320

```