or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbinding-dsl.mdcontainer-configuration.mddirect-access.mdindex.mdlazy-property-delegation.mdscoping-and-context.md

container-configuration.mddocs/

0

# Container Configuration

1

2

Core DI container creation and configuration functionality for managing dependency injection containers, modules, and lifecycle callbacks.

3

4

## Capabilities

5

6

### DI Container Creation

7

8

Creates and configures the main dependency injection container with customizable settings and initialization blocks.

9

10

```kotlin { .api }

11

/**

12

* Main dependency injection container interface

13

*/

14

interface DI : DIAware {

15

val container: DIContainer

16

17

companion object {

18

/**

19

* Creates a DI instance with configuration block

20

* @param allowSilentOverride Whether to allow implicit binding overrides

21

* @param init Configuration block for defining bindings

22

* @return Configured DI container

23

*/

24

operator fun invoke(

25

allowSilentOverride: Boolean = false,

26

init: MainBuilder.() -> Unit

27

): DI

28

29

/**

30

* Creates a lazily initialized DI instance

31

* @param allowSilentOverride Whether to allow implicit binding overrides

32

* @param init Configuration block for defining bindings

33

* @return LazyDI wrapper that initializes on first access

34

*/

35

fun lazy(

36

allowSilentOverride: Boolean = false,

37

init: MainBuilder.() -> Unit

38

): LazyDI

39

40

/**

41

* Creates a direct DI instance for immediate access

42

* @param allowSilentOverride Whether to allow implicit binding overrides

43

* @param init Configuration block for defining bindings

44

* @return DirectDI instance for immediate dependency access

45

*/

46

fun direct(

47

allowSilentOverride: Boolean = false,

48

init: MainBuilder.() -> Unit

49

): DirectDI

50

51

/**

52

* Creates DI with delayed callback execution (internal API)

53

* @param allowSilentOverride Whether to allow implicit binding overrides

54

* @param init Configuration block for defining bindings

55

* @return Pair of DI instance and callback function

56

*/

57

fun withDelayedCallbacks(

58

allowSilentOverride: Boolean = false,

59

init: MainBuilder.() -> Unit

60

): Pair<DI, () -> Unit>

61

62

/**

63

* Creates DI from a list of modules

64

* @param modules List of modules to import

65

* @return DI instance with all module bindings

66

*/

67

fun from(modules: List<Module>): DI

68

69

/** Global default for full error descriptions */

70

var defaultFullDescriptionOnError: Boolean

71

72

/** Global default for full container tree in errors */

73

var defaultFullContainerTreeOnError: Boolean

74

}

75

}

76

```

77

78

### Lazy DI Initialization

79

80

Deferred DI initialization patterns for cases where the container cannot be immediately created.

81

82

```kotlin { .api }

83

/**

84

* Lazily initialized DI container

85

* @param f Function that creates the DI instance when needed

86

*/

87

class LazyDI(f: () -> DI) : DI {

88

// Delegates all DI operations to the lazily created instance

89

}

90

91

/**

92

* Manually initialized DI container for late binding scenarios

93

*/

94

class LateInitDI : DI {

95

/**

96

* The base DI instance (must be set before use)

97

*/

98

lateinit var baseDI: DI

99

}

100

```

101

102

### Module System

103

104

Reusable configuration modules for organizing and sharing binding definitions across DI containers.

105

106

```kotlin { .api }

107

/**

108

* Reusable configuration module for dependency bindings

109

* @param allowSilentOverride Whether this module allows implicit overrides

110

* @param prefix String prefix for all bindings in this module

111

* @param init Configuration block defining the module's bindings

112

*/

113

data class DI.Module(

114

val allowSilentOverride: Boolean = false,

115

val prefix: String = "",

116

val init: Builder.() -> Unit

117

) {

118

val name: String // Module name (required)

119

120

/**

121

* Named module constructor

122

* @param name Unique name for this module

123

* @param allowSilentOverride Whether this module allows implicit overrides

124

* @param prefix String prefix for all bindings in this module

125

* @param init Configuration block defining the module's bindings

126

*/

127

constructor(

128

name: String,

129

allowSilentOverride: Boolean = false,

130

prefix: String = "",

131

init: Builder.() -> Unit

132

)

133

134

/**

135

* Property delegate support for automatic naming

136

*/

137

operator fun getValue(thisRef: Any?, property: KProperty<*>): Module

138

}

139

```

140

141

### Builder Interfaces

142

143

DSL interfaces for configuring DI containers with bindings, modules, and lifecycle callbacks.

144

145

```kotlin { .api }

146

/**

147

* Main builder interface for DI configuration

148

*/

149

interface DI.Builder : BindBuilder<Any>, BindBuilder.WithScope<Any> {

150

val containerBuilder: DIContainer.Builder

151

152

/**

153

* Import a module into this DI configuration

154

* @param module The module to import

155

* @param allowOverride Whether to allow binding overrides

156

*/

157

fun import(module: Module, allowOverride: Boolean = false)

158

159

/**

160

* Import multiple modules into this DI configuration

161

* @param modules Modules to import

162

* @param allowOverride Whether to allow binding overrides

163

*/

164

fun importAll(vararg modules: Module, allowOverride: Boolean = false)

165

fun importAll(modules: Iterable<Module>, allowOverride: Boolean = false)

166

167

/**

168

* Import a module only once (checked by name)

169

* @param module The module to import once

170

* @param allowOverride Whether to allow binding overrides

171

*/

172

fun importOnce(module: Module, allowOverride: Boolean = false)

173

174

/**

175

* Register a callback to be called when DI is ready

176

* @param cb Callback function receiving DirectDI instance

177

*/

178

fun onReady(cb: DirectDI.() -> Unit)

179

180

/**

181

* Register a context translator for scope management

182

* @param translator Context translator instance

183

*/

184

fun RegisterContextTranslator(translator: ContextTranslator<*, *>)

185

}

186

187

/**

188

* Extended builder for main DI creation with additional configuration

189

*/

190

interface DI.MainBuilder : Builder {

191

/** Whether to include qualified names in error messages */

192

var fullDescriptionOnError: Boolean

193

194

/** Whether to include full container tree in NotFoundException */

195

var fullContainerTreeOnError: Boolean

196

197

/** List of external sources for fallback binding resolution */

198

val externalSources: MutableList<ExternalSource>

199

200

/**

201

* Extend this DI with another DI container

202

* @param di The DI container to extend from

203

* @param allowOverride Whether to allow binding overrides

204

* @param copy Copy specification for which bindings to copy

205

*/

206

fun extend(di: DI, allowOverride: Boolean = false, copy: Copy = Copy.NonCached)

207

fun extend(directDI: DirectDI, allowOverride: Boolean = false, copy: Copy = Copy.NonCached)

208

}

209

```

210

211

### Container Extension and Copy Strategies

212

213

Advanced container composition and extension patterns for building complex DI hierarchies.

214

215

```kotlin { .api }

216

/**

217

* Copy specification for container extension

218

*/

219

sealed class Copy {

220

/** Copy no bindings (default) */

221

object None : Copy()

222

223

/** Copy all bindings */

224

object All : Copy()

225

226

/** Copy only non-cached bindings (providers, factories) */

227

object NonCached : Copy()

228

}

229

```

230

231

**Usage Examples:**

232

233

```kotlin

234

// Basic DI container creation

235

val di = DI {

236

bind<DataService>() with singleton { DataServiceImpl() }

237

bind<UserRepository>() with provider { UserRepositoryImpl(instance()) }

238

}

239

240

// Module definition and usage

241

val dataModule = DI.Module("data") {

242

bind<Database>() with singleton { SQLiteDatabase() }

243

bind<UserDao>() with provider { UserDaoImpl(instance()) }

244

}

245

246

val serviceModule = DI.Module("services") {

247

bind<UserService>() with provider { UserServiceImpl(instance()) }

248

}

249

250

val appDI = DI {

251

import(dataModule)

252

import(serviceModule)

253

254

// Override specific bindings

255

bind<Database>(overrides = true) with singleton {

256

if (BuildConfig.DEBUG) MockDatabase() else SQLiteDatabase()

257

}

258

}

259

260

// Lazy DI initialization

261

val lazyDI = DI.lazy {

262

bind<ConfigService>() with singleton { ConfigServiceImpl() }

263

onReady {

264

// Initialization code when DI is ready

265

println("DI container initialized")

266

}

267

}

268

269

// Container extension

270

val extendedDI = DI {

271

extend(appDI, allowOverride = true, copy = Copy.NonCached)

272

273

// Add additional bindings

274

bind<TestService>() with singleton { TestServiceImpl() }

275

}

276

277

// Late initialization pattern

278

class Application : DIAware {

279

private val lateInitDI = LateInitDI()

280

override val di: DI = lateInitDI

281

282

fun initialize() {

283

lateInitDI.baseDI = DI {

284

bind<AppService>() with singleton { AppServiceImpl() }

285

}

286

}

287

}

288

```