or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

containers.mdindex.mdproviders.mdresources.mdschema.mdwiring.md

wiring.mddocs/

0

# Dependency Wiring

1

2

Dependency wiring enables automatic injection of dependencies into functions, methods, and class attributes. It provides decorators and markers for seamless integration with existing code without requiring manual dependency resolution.

3

4

## Capabilities

5

6

### Core Wiring Functions

7

8

Primary functions for setting up and managing dependency injection.

9

10

```python { .api }

11

def wire(container, modules=None, packages=None, from_package=None):

12

"""

13

Wire dependencies into modules and packages.

14

15

Parameters:

16

- container: Container with providers to inject

17

- modules: List of modules to wire

18

- packages: List of packages to wire

19

- from_package: Base package for relative imports

20

"""

21

22

def unwire(container=None, modules=None, packages=None, from_package=None):

23

"""

24

Remove dependency wiring from modules and packages.

25

26

Parameters:

27

- container: Container to unwire (optional)

28

- modules: List of modules to unwire

29

- packages: List of packages to unwire

30

- from_package: Base package for relative imports

31

"""

32

33

def inject(fn):

34

"""

35

Decorator for dependency injection into functions and methods.

36

37

Parameters:

38

- fn: Function or method to inject dependencies into

39

40

Returns:

41

Wrapped function with dependency injection

42

"""

43

```

44

45

Usage example:

46

47

```python

48

from dependency_injector import containers, providers

49

from dependency_injector.wiring import inject, Provide, wire

50

51

# Define container

52

class Container(containers.DeclarativeContainer):

53

user_service = providers.Factory(UserService)

54

55

# Wire container to current module

56

container = Container()

57

wire(container=container, modules=[__name__])

58

59

# Use dependency injection

60

@inject

61

def get_user(user_id: int, service: UserService = Provide[Container.user_service]):

62

return service.get_user(user_id)

63

```

64

65

### Dependency Markers

66

67

Markers specify what and how dependencies should be injected.

68

69

```python { .api }

70

class Provide:

71

"""Marker for dependency injection - provides instance."""

72

def __class_getitem__(cls, provider): ...

73

74

class Provider:

75

"""Marker for provider injection - provides provider object."""

76

def __class_getitem__(cls, provider): ...

77

78

class Closing:

79

"""Marker for resource closing injection."""

80

def __class_getitem__(cls, provider): ...

81

```

82

83

Usage examples:

84

85

```python

86

# Provide instance injection

87

@inject

88

def handler(service: UserService = Provide[Container.user_service]):

89

return service.process()

90

91

# Provider injection (get the provider, not the instance)

92

@inject

93

def factory_handler(service_factory = Provider[Container.user_service]):

94

# Create multiple instances

95

service1 = service_factory()

96

service2 = service_factory()

97

return [service1, service2]

98

99

# Resource closing injection (for cleanup)

100

@inject

101

def process_with_cleanup(

102

database = Provide[Container.database],

103

db_resource = Closing[Container.database]

104

):

105

# Use database

106

result = database.query("SELECT * FROM users")

107

# db_resource will be closed automatically

108

return result

109

```

110

111

### Type Annotations Support

112

113

Wiring supports Python type annotations for cleaner syntax.

114

115

```python

116

from typing import Annotated

117

from dependency_injector.wiring import Provide

118

119

@inject

120

def typed_handler(

121

service: Annotated[UserService, Provide[Container.user_service]]

122

):

123

return service.process()

124

125

# Alternative syntax

126

@inject

127

def alt_handler(service: UserService = Provide[Container.user_service]):

128

return service.process()

129

```

130

131

### Configuration Modifiers

132

133

Modifiers for configuration providers to transform values during injection.

134

135

```python { .api }

136

def as_int():

137

"""Return int type modifier."""

138

139

def as_float():

140

"""Return float type modifier."""

141

142

def as_(type_):

143

"""Return custom type modifier."""

144

145

def required():

146

"""Return required configuration modifier."""

147

148

def invariant(id):

149

"""Return invariant configuration modifier."""

150

151

def provided():

152

"""Return provided instance modifier."""

153

```

154

155

Usage example:

156

157

```python

158

from dependency_injector.wiring import as_int, required, provided

159

160

class Container(containers.DeclarativeContainer):

161

config = providers.Configuration()

162

database = providers.Singleton(Database, host=config.host)

163

164

@inject

165

def configure_app(

166

# Type conversion

167

port: int = Provide[Container.config.port, as_int()],

168

169

# Required configuration

170

secret_key: str = Provide[Container.config.secret_key, required()],

171

172

# Provided instance access

173

db_host: str = Provide[Container.database, provided().host]

174

):

175

app.config["PORT"] = port

176

app.config["SECRET_KEY"] = secret_key

177

app.config["DB_HOST"] = db_host

178

```

179

180

### Class Attribute Injection

181

182

Inject dependencies into class attributes using markers.

183

184

```python

185

from dependency_injector.wiring import Provide

186

187

class UserController:

188

# Class attribute injection

189

user_service = Provide[Container.user_service]

190

config = Provider[Container.config]

191

192

def get_user(self, user_id: int):

193

return self.user_service.get_user(user_id)

194

195

def get_config_value(self, key: str):

196

return self.config().get(key)

197

198

# Wire the container

199

wire(container=container, modules=[__name__])

200

201

# Use the controller

202

controller = UserController()

203

user = controller.get_user(123)

204

```

205

206

### Async Support

207

208

Wiring works seamlessly with async functions and coroutines.

209

210

```python

211

@inject

212

async def async_handler(

213

service: AsyncUserService = Provide[Container.async_user_service]

214

):

215

result = await service.process_async()

216

return result

217

218

@inject

219

async def async_generator(

220

data_service: DataService = Provide[Container.data_service]

221

):

222

async for item in data_service.stream_data():

223

yield item

224

```

225

226

### Framework Integration

227

228

Wiring integrates with popular Python web frameworks.

229

230

#### FastAPI Integration

231

232

```python

233

from fastapi import FastAPI, Depends

234

from dependency_injector.wiring import inject, Provide

235

236

app = FastAPI()

237

238

@app.get("/users/{user_id}")

239

@inject

240

def get_user(

241

user_id: int,

242

service: UserService = Depends(Provide[Container.user_service])

243

):

244

return service.get_user(user_id)

245

246

# Wire the container

247

container.wire(modules=[__name__])

248

```

249

250

#### Flask Integration

251

252

```python

253

from flask import Flask

254

from dependency_injector.wiring import inject, Provide

255

256

app = Flask(__name__)

257

258

@app.route("/users/<int:user_id>")

259

@inject

260

def get_user(user_id: int, service: UserService = Provide[Container.user_service]):

261

return service.get_user(user_id)

262

263

# Wire the container

264

container.wire(modules=[__name__])

265

```

266

267

#### Django Integration

268

269

```python

270

from django.http import JsonResponse

271

from dependency_injector.wiring import inject, Provide

272

273

@inject

274

def user_view(request, user_id, service: UserService = Provide[Container.user_service]):

275

user = service.get_user(user_id)

276

return JsonResponse({"user": user})

277

278

# Wire in Django app configuration

279

container.wire(modules=["myapp.views"])

280

```

281

282

### Auto-Loading

283

284

Automatic wiring of containers when modules are imported.

285

286

```python { .api }

287

class AutoLoader:

288

"""Auto-wiring module loader."""

289

def register_containers(self, *containers): ...

290

def unregister_containers(self, *containers): ...

291

def install(self): ...

292

def uninstall(self): ...

293

294

def register_loader_containers(*containers):

295

"""Register containers in auto-wiring module loader."""

296

297

def unregister_loader_containers(*containers):

298

"""Unregister containers from auto-wiring module loader."""

299

300

def install_loader():

301

"""Install auto-wiring module loader hook."""

302

303

def uninstall_loader():

304

"""Uninstall auto-wiring module loader hook."""

305

306

def is_loader_installed() -> bool:

307

"""Check if auto-wiring module loader hook is installed."""

308

```

309

310

Usage example:

311

312

```python

313

from dependency_injector.wiring import (

314

register_loader_containers,

315

install_loader

316

)

317

318

# Register containers for auto-loading

319

register_loader_containers(container)

320

install_loader()

321

322

# Now any imported module will be automatically wired

323

import myapp.handlers # Automatically wired

324

import myapp.services # Automatically wired

325

```

326

327

### Method Injection Patterns

328

329

Different patterns for injecting dependencies into methods.

330

331

#### Instance Method Injection

332

333

```python

334

class UserController:

335

@inject

336

def get_user(

337

self,

338

user_id: int,

339

service: UserService = Provide[Container.user_service]

340

):

341

return service.get_user(user_id)

342

```

343

344

#### Class Method Injection

345

346

```python

347

class UserService:

348

@classmethod

349

@inject

350

def create_instance(

351

cls,

352

database: Database = Provide[Container.database]

353

):

354

return cls(database)

355

```

356

357

#### Static Method Injection

358

359

```python

360

class UserUtils:

361

@staticmethod

362

@inject

363

def validate_user(

364

user_data: dict,

365

validator: UserValidator = Provide[Container.user_validator]

366

):

367

return validator.validate(user_data)

368

```

369

370

### Error Handling

371

372

Warning and error handling for wiring issues.

373

374

```python { .api }

375

class DIWiringWarning(RuntimeWarning):

376

"""Warning for dependency injection wiring issues."""

377

```

378

379

Common wiring issues and solutions:

380

381

```python

382

# Clear wiring cache if needed

383

from dependency_injector.wiring import clear_cache

384

clear_cache()

385

386

# Handle wiring warnings

387

import warnings

388

from dependency_injector.wiring import DIWiringWarning

389

390

warnings.filterwarnings("ignore", category=DIWiringWarning)

391

```

392

393

### Advanced Wiring Patterns

394

395

#### Conditional Injection

396

397

```python

398

@inject

399

def conditional_handler(

400

service: UserService = Provide[Container.user_service],

401

debug_mode: bool = Provide[Container.config.debug, as_(bool)]

402

):

403

if debug_mode:

404

print(f"Using service: {service}")

405

return service.process()

406

```

407

408

#### Multiple Provider Injection

409

410

```python

411

@inject

412

def multi_service_handler(

413

user_service: UserService = Provide[Container.user_service],

414

email_service: EmailService = Provide[Container.email_service],

415

logger: Logger = Provide[Container.logger]

416

):

417

user = user_service.get_user(123)

418

email_service.send_email(user.email, "Welcome!")

419

logger.info(f"Sent welcome email to {user.email}")

420

```

421

422

#### Resource Cleanup

423

424

```python

425

@inject

426

def process_with_resources(

427

database = Provide[Container.database],

428

redis = Provide[Container.redis],

429

db_cleanup = Closing[Container.database],

430

redis_cleanup = Closing[Container.redis]

431

):

432

# Use resources

433

data = database.query("SELECT * FROM users")

434

redis.set("cache_key", data)

435

436

# Resources will be automatically cleaned up

437

return data

438

```

439

440

## Auto-loading Functions

441

442

Advanced wiring functions for automatic container loading and management.

443

444

```python { .api }

445

def register_loader_containers(*containers):

446

"""Register containers for auto-loading."""

447

448

def unregister_loader_containers(*containers):

449

"""Unregister containers from auto-loading."""

450

451

def install_loader():

452

"""Install auto-wiring loader."""

453

454

def uninstall_loader():

455

"""Uninstall auto-wiring loader."""

456

457

def is_loader_installed() -> bool:

458

"""Check if auto-wiring loader is installed."""

459

460

def clear_cache():

461

"""Clear wiring caches."""

462

```