or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdcomponents.mddependency-injection.mdglobal-context.mdindex.mdmodules.mdscopes.md

components.mddocs/

0

# Component Integration

1

2

Component interfaces and extension functions for seamless dependency injection integration in your classes.

3

4

## Capabilities

5

6

### KoinComponent Interface

7

8

Basic interface for classes that need access to dependency injection.

9

10

```kotlin { .api }

11

/**

12

* Interface for classes that need access to the Koin container

13

* Provides access to dependency injection functionality

14

*/

15

interface KoinComponent {

16

/**

17

* Get the Koin container instance

18

* @return Koin container for dependency resolution

19

*/

20

fun getKoin(): Koin

21

}

22

```

23

24

**Usage Examples:**

25

26

```kotlin

27

import org.koin.core.component.KoinComponent

28

import org.koin.core.component.inject

29

import org.koin.core.component.get

30

31

class UserController : KoinComponent {

32

// Lazy injection using delegate

33

private val userService: UserService by inject()

34

private val emailService: EmailService by inject(named("primary"))

35

36

fun registerUser(userData: UserData): User {

37

val user = userService.createUser(userData)

38

39

// Direct resolution

40

val validator = get<UserValidator>()

41

validator.validate(user)

42

43

emailService.sendWelcomeEmail(user)

44

return user

45

}

46

47

fun handleSpecialCase() {

48

// Access Koin container directly

49

val koin = getKoin()

50

val specialService = koin.getOrNull<SpecialService>()

51

52

if (specialService != null) {

53

specialService.handleSpecialLogic()

54

}

55

}

56

}

57

```

58

59

### KoinComponent Extension Functions

60

61

Extension functions that provide convenient dependency injection methods for KoinComponent implementations.

62

63

```kotlin { .api }

64

/**

65

* Get a dependency instance from the component's Koin container

66

* @param qualifier - Optional qualifier to distinguish multiple instances

67

* @param parameters - Optional parameters to pass to the factory function

68

* @return Instance of the requested type

69

*/

70

inline fun <reified T : Any> KoinComponent.get(qualifier: Qualifier? = null, noinline parameters: ParametersDefinition? = null): T

71

72

/**

73

* Get a lazy dependency from the component's Koin container

74

* @param qualifier - Optional qualifier to distinguish multiple instances

75

* @param mode - Thread safety mode for the lazy delegate

76

* @param parameters - Optional parameters to pass to the factory function

77

* @return Lazy delegate that resolves the dependency on first access

78

*/

79

inline fun <reified T : Any> KoinComponent.inject(qualifier: Qualifier? = null, mode: LazyThreadSafetyMode = KoinPlatformTools.defaultLazyMode(), noinline parameters: ParametersDefinition? = null): Lazy<T>

80

```

81

82

**Usage Examples:**

83

84

```kotlin

85

import org.koin.core.component.KoinComponent

86

import org.koin.core.component.inject

87

import org.koin.core.component.get

88

import org.koin.core.parameter.parametersOf

89

import org.koin.core.qualifier.named

90

91

class OrderService : KoinComponent {

92

// Lazy injection - resolved on first access

93

private val paymentService: PaymentService by inject()

94

private val inventoryService: InventoryService by inject(named("warehouse"))

95

96

// Lazy injection with parameters

97

private val shippingCalculator: ShippingCalculator by inject {

98

parametersOf("standard")

99

}

100

101

// Note: For optional services, use getKoin().getOrNull() in methods

102

103

fun processOrder(order: Order): OrderResult {

104

// Direct resolution when needed

105

val validator = get<OrderValidator>()

106

validator.validateOrder(order)

107

108

// Use injected services

109

val paymentResult = paymentService.processPayment(order.payment)

110

if (!paymentResult.success) {

111

return OrderResult.PaymentFailed

112

}

113

114

// Check inventory

115

val available = inventoryService.checkAvailability(order.items)

116

if (!available) {

117

return OrderResult.OutOfStock

118

}

119

120

// Calculate shipping

121

val shippingCost = shippingCalculator.calculate(order.address, order.items)

122

123

// Apply promotions if available

124

val promotionService = getKoin().getOrNull<PromotionService>()

125

val finalTotal = promotionService?.applyPromotions(order.total) ?: order.total

126

127

return OrderResult.Success(finalTotal + shippingCost)

128

}

129

}

130

```

131

132

### KoinScopeComponent Interface

133

134

Interface for components that manage their own scope lifecycle.

135

136

```kotlin { .api }

137

/**

138

* Interface for components that manage their own scope

139

* Extends KoinComponent with scope management capabilities

140

*/

141

interface KoinScopeComponent : KoinComponent {

142

/**

143

* The scope associated with this component

144

* Components are responsible for managing their scope lifecycle

145

*/

146

val scope: Scope

147

}

148

```

149

150

**Usage Examples:**

151

152

```kotlin

153

import org.koin.core.component.KoinScopeComponent

154

import org.koin.core.scope.Scope

155

import org.koin.core.qualifier.named

156

157

class WebRequestHandler : KoinScopeComponent {

158

// Create scope for this request handler

159

override val scope: Scope by lazy {

160

getKoin().createScope<RequestScope>("request-${generateId()}")

161

}

162

163

// Inject from the component's scope

164

private val requestContext: RequestContext by scope.inject()

165

private val userSession: UserSession by scope.inject()

166

private val requestLogger: RequestLogger by scope.inject()

167

168

fun handleRequest(request: HttpRequest): HttpResponse {

169

requestLogger.logStart(request)

170

171

try {

172

val user = userSession.getCurrentUser()

173

val response = processRequest(request, user)

174

requestLogger.logSuccess(response)

175

return response

176

} catch (e: Exception) {

177

requestLogger.logError(e)

178

throw e

179

}

180

}

181

182

fun cleanup() {

183

// Close scope when component is done

184

scope.close()

185

}

186

}

187

188

// Usage pattern with try-finally

189

class RequestProcessor {

190

fun processRequest(requestData: RequestData) {

191

val handler = WebRequestHandler()

192

try {

193

val response = handler.handleRequest(requestData.toHttpRequest())

194

// Handle response...

195

} finally {

196

handler.cleanup() // Ensure scope is closed

197

}

198

}

199

}

200

```

201

202

### KoinScopeComponent Extension Functions

203

204

Extension functions that provide scope management utilities for KoinScopeComponent implementations.

205

206

```kotlin { .api }

207

/**

208

* Get the scope ID for any object based on its class name

209

* @param T - Type of the object

210

* @return Generated scope ID string

211

*/

212

fun <T : Any> T.getScopeId(): String

213

214

/**

215

* Get the scope name (type qualifier) for any object

216

* @param T - Type of the object

217

* @return TypeQualifier based on the object's class

218

*/

219

fun <T : Any> T.getScopeName(): TypeQualifier

220

221

/**

222

* Create a scope for a KoinScopeComponent

223

* @param scopeId - Scope identifier (default: generated from object)

224

* @param source - Optional source object

225

* @param scopeArchetype - Optional scope archetype

226

* @return New Scope instance

227

*/

228

fun <T : KoinScopeComponent> T.createScope(scopeId: ScopeID = getScopeId(), source: Any? = null, scopeArchetype: TypeQualifier? = null): Scope

229

230

/**

231

* Create a scope for a KoinScopeComponent with source

232

* @param source - Source object for the scope

233

* @return New Scope instance

234

*/

235

fun <T : KoinScopeComponent> T.createScope(source: Any? = null): Scope

236

237

/**

238

* Get the scope for a KoinScopeComponent or null if not created

239

* @return Existing scope or null

240

*/

241

fun <T : KoinScopeComponent> T.getScopeOrNull(): Scope?

242

243

/**

244

* Create a new scope lazily for a KoinScopeComponent

245

* @return Lazy delegate that creates the scope on first access

246

*/

247

fun <T : KoinScopeComponent> T.newScope(): Lazy<Scope>

248

249

/**

250

* Get existing scope or create a new one lazily for a KoinScopeComponent

251

* @return Lazy delegate that gets or creates the scope on first access

252

*/

253

fun <T : KoinScopeComponent> T.getOrCreateScope(): Lazy<Scope>

254

```

255

256

**Usage Examples:**

257

258

```kotlin

259

import org.koin.core.component.KoinScopeComponent

260

import org.koin.core.component.*

261

262

// Different scope creation patterns

263

class UserSessionManager : KoinScopeComponent {

264

// Option 1: Create scope immediately

265

override val scope: Scope = createScope(source = this)

266

267

private val sessionStore: SessionStore by scope.inject()

268

private val userCache: UserCache by scope.inject()

269

}

270

271

class LazySessionManager : KoinScopeComponent {

272

// Option 2: Create scope lazily

273

override val scope: Scope by newScope()

274

275

private val sessionStore: SessionStore by scope.inject()

276

}

277

278

class AdaptiveSessionManager : KoinScopeComponent {

279

// Option 3: Get or create scope lazily

280

override val scope: Scope by getOrCreateScope()

281

282

private val sessionStore: SessionStore by scope.inject()

283

284

fun initializeSession(userId: String) {

285

// Scope is created here on first access

286

scope.declare(UserId(userId))

287

288

// Generate scope ID for debugging

289

val scopeId = getScopeId()

290

val scopeName = getScopeName()

291

println("Session scope: $scopeName ($scopeId)")

292

}

293

}

294

295

// Usage with explicit scope management

296

class RequestScopedService : KoinScopeComponent {

297

override val scope: Scope by lazy {

298

val myScope = createScope("custom-${System.currentTimeMillis()}")

299

300

// Register cleanup callback

301

myScope.registerCallback(object : ScopeCallback {

302

override fun onScopeCreated(qualifier: Qualifier, scope: Scope) {

303

println("Scope created: ${scope.id}")

304

}

305

306

override fun onScopeClosed(qualifier: Qualifier, scope: Scope) {

307

println("Scope closed: ${scope.id}")

308

}

309

})

310

311

myScope

312

}

313

314

private val requestProcessor: RequestProcessor by scope.inject()

315

316

fun processAndCleanup() {

317

try {

318

requestProcessor.process()

319

} finally {

320

// Check if scope exists before closing

321

getScopeOrNull()?.close()

322

}

323

}

324

}

325

```

326

327

### Component Patterns

328

329

Common patterns for using components effectively.

330

331

**Singleton Component Pattern:**

332

333

```kotlin

334

// Global singleton component

335

object ApplicationServices : KoinComponent {

336

val configService: ConfigService by inject()

337

val logService: LogService by inject()

338

339

fun initialize() {

340

configService.loadConfiguration()

341

logService.initialize()

342

}

343

}

344

345

// Usage

346

ApplicationServices.initialize()

347

val config = ApplicationServices.configService.getConfig("app.name")

348

```

349

350

**Factory Component Pattern:**

351

352

```kotlin

353

// Component factory for creating instances

354

class ComponentFactory : KoinComponent {

355

fun createUserProcessor(userId: String): UserProcessor {

356

return get<UserProcessor> { parametersOf(userId) }

357

}

358

359

fun createApiClient(endpoint: String): ApiClient {

360

return get<ApiClient> { parametersOf(endpoint) }

361

}

362

}

363

364

// Usage

365

val factory = ComponentFactory()

366

val processor = factory.createUserProcessor("user-123")

367

val client = factory.createApiClient("https://api.example.com")

368

```

369

370

**Scoped Component Lifecycle Pattern:**

371

372

```kotlin

373

// Base class for scoped components

374

abstract class ScopedComponent : KoinScopeComponent {

375

abstract val scopeQualifier: Qualifier

376

377

override val scope: Scope by lazy {

378

getKoin().createScope("${scopeQualifier.value}-${generateId()}", scopeQualifier)

379

}

380

381

open fun initialize() {

382

// Subclasses can override for initialization

383

}

384

385

open fun cleanup() {

386

if (!scope.closed) {

387

scope.close()

388

}

389

}

390

}

391

392

// Request-scoped component

393

class RequestComponent : ScopedComponent() {

394

override val scopeQualifier = named("request")

395

396

private val requestHandler: RequestHandler by scope.inject()

397

private val requestValidator: RequestValidator by scope.inject()

398

399

override fun initialize() {

400

// Request-specific initialization

401

scope.declare(RequestId(generateRequestId()))

402

}

403

}

404

405

// Usage with automatic cleanup

406

inline fun <T> withRequestComponent(block: (RequestComponent) -> T): T {

407

val component = RequestComponent()

408

return try {

409

component.initialize()

410

block(component)

411

} finally {

412

component.cleanup()

413

}

414

}

415

416

// Usage

417

withRequestComponent { component ->

418

val result = component.requestHandler.handle(request)

419

// Component is automatically cleaned up

420

result

421

}

422

```

423

424

## Type Definitions

425

426

```kotlin { .api }

427

/**

428

* Base interface for dependency injection components

429

*/

430

interface KoinComponent {

431

fun getKoin(): Koin

432

}

433

434

/**

435

* Interface for components with scope management

436

*/

437

interface KoinScopeComponent : KoinComponent {

438

val scope: Scope

439

}

440

441

/**

442

* Generate a unique ID for scopes and components

443

* @return Generated unique identifier string

444

*/

445

fun generateId(): String

446

447

/**

448

* Type alias for type-based qualifiers

449

*/

450

class TypeQualifier : Qualifier {

451

val type: KClass<*>

452

}

453

```