or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-setup.mdcomponent-integration.mdconfiguration-logging.mdconstructor-reference.mdindex.mdjava-interop.mdmodule-definition.mdproperty-management.mdqualifiers-parameters.mdscope-management.md

qualifiers-parameters.mddocs/

0

# Qualifiers & Parameters

1

2

Type-safe qualifier system for distinguishing between multiple instances of the same type, and parameter injection for runtime dependency configuration. Essential for complex dependency scenarios and runtime parameter passing.

3

4

## Capabilities

5

6

### Qualifier Interface

7

8

Base interface for creating type-safe qualifiers to distinguish between instances.

9

10

```kotlin { .api }

11

/**

12

* Base qualifier interface for distinguishing instances

13

*/

14

interface Qualifier {

15

/**

16

* String value of the qualifier

17

*/

18

val value: String

19

}

20

```

21

22

### String-Based Qualifiers

23

24

Create qualifiers using string values for simple naming scenarios.

25

26

```kotlin { .api }

27

/**

28

* Create string-based qualifier

29

* @param name - String identifier for the qualifier

30

* @return Qualifier instance

31

*/

32

fun named(name: String): Qualifier

33

34

/**

35

* Create enum-based qualifier

36

* @param name - Enum value for the qualifier

37

* @return Qualifier instance

38

*/

39

fun named(name: Enum<*>): Qualifier

40

41

/**

42

* Alternative string qualifier function

43

* @param name - String identifier for the qualifier

44

* @return Qualifier instance

45

*/

46

fun qualifier(name: String): Qualifier

47

48

/**

49

* Alternative enum qualifier function

50

* @param name - Enum value for the qualifier

51

* @return Qualifier instance

52

*/

53

fun qualifier(name: Enum<*>): Qualifier

54

55

/**

56

* Short form string qualifier

57

* @param name - String identifier for the qualifier

58

* @return Qualifier instance

59

*/

60

fun _q(name: String): Qualifier

61

```

62

63

**Usage Examples:**

64

65

```kotlin

66

import org.koin.core.qualifier.named

67

import org.koin.core.qualifier.qualifier

68

import org.koin.core.qualifier._q

69

import org.koin.dsl.module

70

71

enum class DatabaseType { PRIMARY, CACHE, ANALYTICS }

72

73

val qualifierModule = module {

74

// String qualifiers

75

single<Database>(named("primary")) { PostgreSQLDatabase() }

76

single<Database>(named("cache")) { RedisDatabase() }

77

single<Database>(qualifier("analytics")) { ClickHouseDatabase() }

78

79

// Enum qualifiers

80

single<ApiClient>(named(DatabaseType.PRIMARY)) { PrimaryApiClient() }

81

single<ApiClient>(named(DatabaseType.CACHE)) { CacheApiClient() }

82

83

// Short form qualifiers

84

single<Logger>(_q("file")) { FileLogger() }

85

single<Logger>(_q("console")) { ConsoleLogger() }

86

87

// Using qualifiers in dependencies

88

single<UserService> {

89

UserServiceImpl(

90

database = get(named("primary")),

91

cache = get(named("cache")),

92

logger = get(_q("file"))

93

)

94

}

95

}

96

97

// Usage in components

98

class DataService : KoinComponent {

99

private val primaryDb: Database by inject(named("primary"))

100

private val cacheDb: Database by inject(named("cache"))

101

private val analyticsDb: Database by inject(qualifier("analytics"))

102

103

fun processData() {

104

val data = primaryDb.query("SELECT * FROM users")

105

cacheDb.store("users", data)

106

analyticsDb.track("users_queried", data.size)

107

}

108

}

109

```

110

111

### Type-Based Qualifiers

112

113

Create qualifiers using type information for strongly-typed scenarios.

114

115

```kotlin { .api }

116

/**

117

* Create type-based qualifier using reified generics

118

* @return Type qualifier based on T

119

*/

120

inline fun <reified T> named(): Qualifier

121

122

/**

123

* Create type-based qualifier using reified generics

124

* @return Type qualifier based on T

125

*/

126

inline fun <reified T> qualifier(): Qualifier

127

128

/**

129

* Short form type-based qualifier

130

* @return Type qualifier based on T

131

*/

132

inline fun <reified T> _q(): Qualifier

133

134

/**

135

* Type-based qualifier implementation

136

* @param type - KClass representing the type

137

*/

138

class TypeQualifier(type: KClass<*>) : Qualifier

139

```

140

141

**Usage Examples:**

142

143

```kotlin

144

import org.koin.core.qualifier.named

145

import org.koin.core.qualifier.qualifier

146

import org.koin.core.qualifier._q

147

import org.koin.dsl.module

148

149

// Marker classes for type qualifiers

150

class PrimaryDatabase

151

class CacheDatabase

152

class AnalyticsDatabase

153

154

val typeQualifierModule = module {

155

// Type-based qualifiers

156

single<Database>(named<PrimaryDatabase>()) { PostgreSQLDatabase() }

157

single<Database>(qualifier<CacheDatabase>()) { RedisDatabase() }

158

single<Database>(_q<AnalyticsDatabase>()) { ClickHouseDatabase() }

159

160

// Scope qualifiers using types

161

scope(named<UserScope>()) {

162

scoped<UserService> { UserServiceImpl(get(named<PrimaryDatabase>())) }

163

scoped<UserCache> { UserCacheImpl(get(qualifier<CacheDatabase>())) }

164

}

165

}

166

167

// Usage with type safety

168

class AnalyticsService : KoinComponent {

169

private val analyticsDb: Database by inject(_q<AnalyticsDatabase>())

170

private val primaryDb: Database by inject(named<PrimaryDatabase>())

171

172

fun generateReport() {

173

val data = primaryDb.query("SELECT * FROM analytics")

174

val report = analyticsDb.process(data)

175

// Process report...

176

}

177

}

178

```

179

180

### Qualifier Implementations

181

182

Built-in qualifier implementations for different use cases.

183

184

```kotlin { .api }

185

/**

186

* String-based qualifier implementation

187

* @param value - String identifier

188

*/

189

data class StringQualifier(override val value: String) : Qualifier

190

191

/**

192

* Type-based qualifier implementation

193

* @param type - KClass representing the type

194

*/

195

class TypeQualifier(type: KClass<*>) : Qualifier {

196

override val value: String

197

}

198

199

typealias QualifierValue = String

200

```

201

202

**Usage Examples:**

203

204

```kotlin

205

import org.koin.core.qualifier.StringQualifier

206

import org.koin.core.qualifier.TypeQualifier

207

208

class CustomQualifierService : KoinComponent {

209

210

fun demonstrateQualifiers() {

211

// Create qualifiers programmatically

212

val stringQual = StringQualifier("custom")

213

val typeQual = TypeQualifier(String::class)

214

215

// Use in dependency resolution

216

val customService = get<MyService>(stringQual)

217

val typedService = get<MyService>(typeQual)

218

219

// Qualifier values are accessible

220

println("String qualifier: ${stringQual.value}")

221

println("Type qualifier: ${typeQual.value}")

222

}

223

}

224

```

225

226

### Parameter System

227

228

Runtime parameter injection for dynamic dependency configuration.

229

230

```kotlin { .api }

231

/**

232

* Parameter container for dependency injection

233

* @param values - Mutable list of parameter values

234

* @param useIndexedValues - Whether to use indexed parameter access

235

*/

236

class ParametersHolder(

237

private val values: MutableList<Any?> = mutableListOf(),

238

private val useIndexedValues: Boolean? = null

239

) {

240

/**

241

* Get parameter by index

242

* @param index - Parameter index

243

* @return Parameter value cast to T

244

*/

245

fun <T> get(index: Int): T

246

247

/**

248

* Get parameter by index with null safety

249

* @param index - Parameter index

250

* @return Parameter value cast to T or null

251

*/

252

fun <T> getOrNull(index: Int): T?

253

254

/**

255

* Set parameter at index

256

* @param index - Parameter index

257

* @param value - Parameter value

258

*/

259

fun <T> set(index: Int, value: T)

260

261

/**

262

* Get parameter at index (alias for get)

263

* @param index - Parameter index

264

* @return Parameter value cast to T

265

*/

266

fun <T> elementAt(index: Int): T

267

268

/**

269

* Get number of parameters

270

* @return Parameter count

271

*/

272

fun size(): Int

273

274

/**

275

* Check if parameters are empty

276

* @return True if no parameters

277

*/

278

fun isEmpty(): Boolean

279

280

/**

281

* Add parameter to end

282

* @param value - Parameter value

283

*/

284

fun add(value: Any?)

285

286

/**

287

* Insert parameter at index

288

* @param index - Target index

289

* @param value - Parameter value

290

*/

291

fun insert(index: Int, value: Any?)

292

293

// Component functions for destructuring

294

operator fun component1(): Any?

295

operator fun component2(): Any?

296

operator fun component3(): Any?

297

operator fun component4(): Any?

298

operator fun component5(): Any?

299

}

300

```

301

302

### Parameter Factory Functions

303

304

Create parameter holders using different patterns.

305

306

```kotlin { .api }

307

/**

308

* Create parameters from variable arguments

309

* @param values - Variable number of parameter values

310

* @return ParametersHolder with values

311

*/

312

fun parametersOf(vararg values: Any?): ParametersHolder

313

314

/**

315

* Create indexed parameters from array

316

* @param values - Array of parameter values

317

* @return ParametersHolder with indexed access

318

*/

319

fun parameterArrayOf(vararg values: Any?): ParametersHolder

320

321

/**

322

* Create parameters from set/collection

323

* @param values - Set of parameter values

324

* @return ParametersHolder with set-based values

325

*/

326

fun parameterSetOf(vararg values: Any?): ParametersHolder

327

328

/**

329

* Create empty parameter holder

330

* @return Empty ParametersHolder

331

*/

332

fun emptyParametersHolder(): ParametersHolder

333

```

334

335

**Usage Examples:**

336

337

```kotlin

338

import org.koin.core.parameter.parametersOf

339

import org.koin.core.parameter.parameterArrayOf

340

import org.koin.core.parameter.emptyParametersHolder

341

import org.koin.dsl.module

342

343

// Module with parameterized dependencies

344

val parameterModule = module {

345

factory<HttpClient> { params ->

346

val baseUrl = params.get<String>(0)

347

val timeout = params.get<Int>(1)

348

val retries = params.getOrNull<Int>(2) ?: 3

349

HttpClientImpl(baseUrl, timeout, retries)

350

}

351

352

factory<DatabaseConnection> { params ->

353

val (host, port, database, user, password) = params

354

DatabaseConnectionImpl(host as String, port as Int, database as String, user as String, password as String)

355

}

356

}

357

358

// Usage with parameters

359

class NetworkService : KoinComponent {

360

361

fun createClients() {

362

// Simple parameters

363

val apiClient = get<HttpClient> {

364

parametersOf("https://api.example.com", 30)

365

}

366

367

// Parameters with optional values

368

val clientWithRetries = get<HttpClient> {

369

parametersOf("https://api.example.com", 60, 5)

370

}

371

372

// Array parameters

373

val configuredClient = get<HttpClient> {

374

parameterArrayOf("https://secure-api.example.com", 45)

375

}

376

377

// Destructured parameters

378

val dbConnection = get<DatabaseConnection> {

379

parametersOf("localhost", 5432, "myapp", "user", "password")

380

}

381

382

// Empty parameters

383

val defaultService = get<DefaultService> { emptyParametersHolder() }

384

}

385

}

386

```

387

388

### Parameter Usage in Definitions

389

390

Use parameters within dependency definitions for dynamic configuration.

391

392

```kotlin { .api }

393

typealias ParametersDefinition = () -> ParametersHolder

394

```

395

396

**Usage Examples:**

397

398

```kotlin

399

import org.koin.dsl.module

400

import org.koin.core.parameter.parametersOf

401

402

val dynamicModule = module {

403

404

// Single with parameters

405

single<ApiService> { params ->

406

val baseUrl = params.get<String>(0)

407

val apiKey = params.getOrNull<String>(1) ?: "default-key"

408

ApiServiceImpl(baseUrl, apiKey)

409

}

410

411

// Factory with parameter validation

412

factory<UserValidator> { params ->

413

val rules = params.get<ValidationRules>(0)

414

val strict = params.getOrNull<Boolean>(1) ?: false

415

416

require(rules.isValid()) { "Invalid validation rules" }

417

UserValidatorImpl(rules, strict)

418

}

419

420

// Scoped with complex parameters

421

scope(named<SessionScope>()) {

422

scoped<SessionManager> { params ->

423

val userId = params.get<String>(0)

424

val permissions = params.get<Set<Permission>>(1)

425

val config = params.getOrNull<SessionConfig>(2) ?: SessionConfig.default()

426

427

SessionManagerImpl(userId, permissions, config)

428

}

429

}

430

}

431

432

// Advanced parameter usage

433

class ConfigurableService : KoinComponent {

434

435

fun createDynamicServices() {

436

// Configuration-driven parameters

437

val config = loadConfiguration()

438

439

val apiService = get<ApiService> {

440

parametersOf(config.apiUrl, config.apiKey)

441

}

442

443

// Runtime-computed parameters

444

val validator = get<UserValidator> {

445

parametersOf(

446

computeValidationRules(),

447

isStrictModeEnabled()

448

)

449

}

450

451

// Nested parameter creation

452

val sessionManager = get<SessionManager> {

453

parametersOf(

454

getCurrentUserId(),

455

getUserPermissions(),

456

SessionConfig.builder()

457

.timeout(config.sessionTimeout)

458

.secure(config.isSecure)

459

.build()

460

)

461

}

462

}

463

}

464

```

465

466

### Parameter Validation & Error Handling

467

468

Handle parameter-related errors and validation.

469

470

```kotlin { .api }

471

// Parameter-related exceptions

472

class NoParameterFoundException(message: String) : RuntimeException(message)

473

class DefinitionParameterException(message: String) : RuntimeException(message)

474

```

475

476

**Usage Examples:**

477

478

```kotlin

479

import org.koin.dsl.module

480

import org.koin.core.parameter.parametersOf

481

482

val validatedModule = module {

483

factory<EmailService> { params ->

484

try {

485

val smtpHost = params.get<String>(0)

486

val port = params.get<Int>(1)

487

val username = params.getOrNull<String>(2)

488

val password = params.getOrNull<String>(3)

489

490

// Validate parameters

491

require(smtpHost.isNotBlank()) { "SMTP host cannot be blank" }

492

require(port in 1..65535) { "Port must be between 1 and 65535" }

493

494

EmailServiceImpl(smtpHost, port, username, password)

495

} catch (e: Exception) {

496

throw DefinitionParameterException("Failed to create EmailService: ${e.message}")

497

}

498

}

499

}

500

501

class EmailController : KoinComponent {

502

503

fun sendEmail() {

504

try {

505

val emailService = get<EmailService> {

506

parametersOf("smtp.example.com", 587, "user@example.com", "password")

507

}

508

emailService.send("Hello World!")

509

} catch (e: NoParameterFoundException) {

510

logger.error("Missing required parameters for EmailService")

511

} catch (e: DefinitionParameterException) {

512

logger.error("Invalid parameters for EmailService: ${e.message}")

513

}

514

}

515

}

516

```

517

518

## Best Practices

519

520

### Qualifier Naming Conventions

521

522

```kotlin

523

// Use descriptive names

524

single<Database>(named("userDatabase")) { UserDatabase() }

525

single<Database>(named("analyticsDatabase")) { AnalyticsDatabase() }

526

527

// Use enums for related qualifiers

528

enum class CacheType { MEMORY, REDIS, DISK }

529

single<Cache>(named(CacheType.MEMORY)) { MemoryCache() }

530

single<Cache>(named(CacheType.REDIS)) { RedisCache() }

531

532

// Use type qualifiers for marker interfaces

533

interface Primary

534

interface Secondary

535

single<Service>(named<Primary>()) { PrimaryService() }

536

single<Service>(named<Secondary>()) { SecondaryService() }

537

```

538

539

### Parameter Patterns

540

541

```kotlin

542

// Use parameter objects for complex configurations

543

data class DatabaseConfig(

544

val host: String,

545

val port: Int,

546

val database: String,

547

val credentials: Credentials

548

)

549

550

factory<DatabaseConnection> { params ->

551

val config = params.get<DatabaseConfig>(0)

552

DatabaseConnectionImpl(config)

553

}

554

555

// Use builders for optional parameters

556

factory<HttpClient> { params ->

557

val builder = HttpClient.Builder()

558

.baseUrl(params.get<String>(0))

559

.timeout(params.getOrNull<Int>(1) ?: 30)

560

561

params.getOrNull<Map<String, String>>(2)?.let { headers ->

562

builder.headers(headers)

563

}

564

565

builder.build()

566

}

567

```

568

569

## Types

570

571

```kotlin { .api }

572

typealias ParametersDefinition = () -> ParametersHolder

573

typealias QualifierValue = String

574

575

// Parameter access interface

576

interface ParameterAccess {

577

fun <T> get(index: Int): T

578

fun <T> getOrNull(index: Int): T?

579

fun size(): Int

580

fun isEmpty(): Boolean

581

}

582

```