or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-startup.mdcontext-management.mddependency-injection.mderror-handling.mdindex.mdlogging-system.mdmodule-system.mdqualifiers-parameters.mdscoping-lifecycle.md

qualifiers-parameters.mddocs/

0

# Qualifiers and Parameters

1

2

Type-safe dependency identification and parameter injection for complex dependency graphs and runtime configuration.

3

4

## Capabilities

5

6

### Qualifier System

7

8

Use qualifiers to differentiate between multiple instances of the same type.

9

10

```javascript { .api }

11

interface Qualifier {

12

/**

13

* Qualifier value for unique identification

14

*/

15

value: any;

16

}

17

18

/**

19

* Create named string-based qualifier

20

* @param name - Qualifier name

21

* @returns StringQualifier instance

22

*/

23

function named(name: string): Qualifier;

24

25

/**

26

* Create type-based qualifier using generics

27

* @returns TypeQualifier instance

28

*/

29

function named<T>(): Qualifier;

30

31

/**

32

* Create string qualifier (alias for named)

33

* @param name - Qualifier name

34

* @returns StringQualifier instance

35

*/

36

function qualifier(name: string): Qualifier;

37

38

/**

39

* Create type qualifier (alias for named)

40

* @returns TypeQualifier instance

41

*/

42

function qualifier<T>(): Qualifier;

43

44

/**

45

* Short qualifier function for string

46

* @param name - Qualifier name

47

* @returns StringQualifier instance

48

*/

49

function _q(name: string): Qualifier;

50

51

/**

52

* Short qualifier function for type

53

* @returns TypeQualifier instance

54

*/

55

function _q<T>(): Qualifier;

56

```

57

58

**Usage Examples:**

59

60

```javascript

61

import { module, named, qualifier, _q } from "koin-core";

62

63

const databaseModule = module((builder) => {

64

// Multiple database connections with qualifiers

65

builder.single(named("primary"), () =>

66

new DatabaseConnection("primary-db:5432")

67

);

68

69

builder.single(named("secondary"), () =>

70

new DatabaseConnection("secondary-db:5432")

71

);

72

73

builder.single(named("cache"), () =>

74

new DatabaseConnection("redis:6379")

75

);

76

77

// Multiple loggers with type qualifiers

78

builder.single(qualifier("console"), () => new ConsoleLogger());

79

builder.single(qualifier("file"), () => new FileLogger("/var/log/app.log"));

80

81

// Short syntax qualifiers

82

builder.factory(_q("temp"), () => new TemporaryStorage());

83

builder.factory(_q("persistent"), () => new PersistentStorage());

84

});

85

86

// Using qualified dependencies

87

class UserService extends KoinComponent {

88

constructor() {

89

super();

90

this.primaryDb = this.get(named("primary")); // Primary database

91

this.cacheDb = this.get(named("cache")); // Cache database

92

this.logger = this.get(qualifier("file")); // File logger

93

this.storage = this.get(_q("persistent")); // Persistent storage

94

}

95

}

96

```

97

98

### Qualifier Types

99

100

Different qualifier implementations for various identification strategies.

101

102

```javascript { .api }

103

/**

104

* String-based qualifier for named identification

105

*/

106

class StringQualifier implements Qualifier {

107

constructor(name: string);

108

value: string;

109

toString(): string;

110

}

111

112

/**

113

* Type-based qualifier for class-based identification

114

*/

115

class TypeQualifier implements Qualifier {

116

constructor(type: any);

117

value: any;

118

toString(): string;

119

}

120

```

121

122

**Usage Examples:**

123

124

```javascript

125

import { StringQualifier, TypeQualifier } from "koin-core";

126

127

// Manual qualifier creation

128

const primaryQualifier = new StringQualifier("primary");

129

const typeQualifier = new TypeQualifier(DatabaseService);

130

131

// Using in module definitions

132

const manualModule = module((builder) => {

133

builder.single(primaryQualifier, () => new PrimaryService());

134

builder.single(typeQualifier, () => new DatabaseService());

135

});

136

137

// Qualifier comparison and identification

138

function logQualifier(qualifier) {

139

console.log(`Qualifier: ${qualifier.toString()}`);

140

console.log(`Value: ${qualifier.value}`);

141

}

142

143

logQualifier(named("test")); // "Qualifier: test, Value: test"

144

logQualifier(named<UserService>()); // "Qualifier: UserService, Value: [class]"

145

```

146

147

### Parameter System

148

149

Pass parameters during dependency resolution for dynamic instance creation.

150

151

```javascript { .api }

152

/**

153

* Create parameters holder with ordered values

154

* @param parameters - Parameter values in injection order

155

* @returns ParametersHolder for injection

156

*/

157

function parametersOf(...parameters: any[]): ParametersHolder;

158

159

/**

160

* Create indexed parameter array for array-like access

161

* @param parameters - Parameter values

162

* @returns ParametersHolder with indexed access

163

*/

164

function parameterArrayOf(...parameters: any[]): ParametersHolder;

165

166

/**

167

* Create parameter set for type-based parameter access

168

* @param parameters - Parameter values

169

* @returns ParametersHolder with type-based access

170

*/

171

function parameterSetOf(...parameters: any[]): ParametersHolder;

172

173

/**

174

* Create empty parameters holder

175

* @returns Empty ParametersHolder

176

*/

177

function emptyParametersHolder(): ParametersHolder;

178

```

179

180

**Usage Examples:**

181

182

```javascript

183

import {

184

parametersOf,

185

parameterArrayOf,

186

parameterSetOf,

187

emptyParametersHolder

188

} from "koin-core";

189

190

// Different parameter creation methods

191

const orderedParams = parametersOf("localhost", 5432, "myapp", true);

192

const arrayParams = parameterArrayOf("item1", "item2", "item3");

193

const typedParams = parameterSetOf(new Date(), "config", 100);

194

const noParams = emptyParametersHolder();

195

196

// Usage in dependency injection

197

class DatabaseService extends KoinComponent {

198

async connect(host, port, database, ssl = false) {

199

const connection = this.get(named("dynamic"), () =>

200

parametersOf(host, port, database, ssl)

201

);

202

203

return await connection.connect();

204

}

205

}

206

```

207

208

### Parameter Access

209

210

Access and retrieve parameters within dependency definitions.

211

212

```javascript { .api }

213

class ParametersHolder {

214

/**

215

* Get parameter by index with optional type checking

216

* @param index - Parameter index (0-based)

217

* @param clazz - Optional expected parameter type

218

* @returns Parameter value of type T

219

* @throws NoParameterFoundException if index out of bounds

220

*/

221

elementAt<T>(index: number, clazz?: new (...args: any[]) => T): T;

222

223

/**

224

* Get parameter by type - returns first matching type

225

* @returns Parameter value of type T

226

* @throws NoParameterFoundException if type not found

227

*/

228

get<T>(): T;

229

230

/**

231

* Check if parameters are empty

232

* @returns true if no parameters

233

*/

234

isEmpty(): boolean;

235

236

/**

237

* Check if parameters exist

238

* @returns true if parameters are present

239

*/

240

isNotEmpty(): boolean;

241

242

/**

243

* Get parameter count

244

* @returns Number of parameters

245

*/

246

size(): number;

247

248

/**

249

* Get parameter values as array

250

* @returns Array of all parameter values

251

*/

252

values(): any[];

253

}

254

```

255

256

**Usage Examples:**

257

258

```javascript

259

import { module, parametersOf } from "koin-core";

260

261

// Module with parameter-accepting definitions

262

const dynamicModule = module((builder) => {

263

builder.factory((scope, params) => {

264

// Access parameters by index

265

const host = params.elementAt(0); // string

266

const port = params.elementAt(1); // number

267

const ssl = params.elementAt(2); // boolean

268

269

return new DatabaseConnection(host, port, ssl);

270

});

271

272

builder.single((scope, params) => {

273

// Access parameters by type

274

const config = params.get(); // ConfigObject

275

const logger = params.get(); // Logger

276

277

return new ConfigurationService(config, logger);

278

});

279

280

builder.factory((scope, params) => {

281

// Parameter validation and defaults

282

if (params.isEmpty()) {

283

return new DefaultApiClient();

284

}

285

286

const baseUrl = params.size() > 0 ? params.elementAt(0) : "https://api.default.com";

287

const timeout = params.size() > 1 ? params.elementAt(1) : 5000;

288

289

return new ApiClient(baseUrl, timeout);

290

});

291

});

292

293

// Using parameters in injection

294

class ServiceManager extends KoinComponent {

295

async createDatabaseConnection(host, port, useSSL) {

296

const connection = this.get(named("database"), () =>

297

parametersOf(host, port, useSSL)

298

);

299

300

return connection;

301

}

302

303

async createConfiguredService() {

304

const config = new ConfigObject({ env: "production" });

305

const logger = new FileLogger("/var/log/service.log");

306

307

const service = this.get(named("configured"), () =>

308

parametersOf(config, logger)

309

);

310

311

return service;

312

}

313

}

314

```

315

316

### Destructuring Support

317

318

Use destructuring syntax for convenient parameter access.

319

320

```javascript { .api }

321

class ParametersHolder {

322

/**

323

* Destructuring support - get first parameter

324

* @returns First parameter value

325

*/

326

component1<T>(): T;

327

328

/**

329

* Destructuring support - get second parameter

330

* @returns Second parameter value

331

*/

332

component2<T>(): T;

333

334

/**

335

* Destructuring support - get third parameter

336

* @returns Third parameter value

337

*/

338

component3<T>(): T;

339

340

/**

341

* Destructuring support - get fourth parameter

342

* @returns Fourth parameter value

343

*/

344

component4<T>(): T;

345

346

/**

347

* Destructuring support - get fifth parameter

348

* @returns Fifth parameter value

349

*/

350

component5<T>(): T;

351

}

352

```

353

354

**Usage Examples:**

355

356

```javascript

357

import { module, parametersOf } from "koin-core";

358

359

const destructuringModule = module((builder) => {

360

builder.factory((scope, params) => {

361

// Destructuring parameter access

362

const host = params.component1(); // First parameter

363

const port = params.component2(); // Second parameter

364

const database = params.component3(); // Third parameter

365

const username = params.component4(); // Fourth parameter

366

const password = params.component5(); // Fifth parameter

367

368

return new DatabaseConfig(host, port, database, username, password);

369

});

370

371

builder.single((scope, params) => {

372

// Mixed access patterns

373

const [baseUrl, timeout] = [params.component1(), params.component2()];

374

const retries = params.elementAt(2, Number); // Type-checked access

375

376

return new HttpClientConfig(baseUrl, timeout, retries);

377

});

378

});

379

380

// Usage with destructuring

381

class ConfigurationManager extends KoinComponent {

382

async setupDatabase() {

383

const dbConfig = this.get(named("database"), () =>

384

parametersOf(

385

"prod-db.example.com",

386

5432,

387

"production_db",

388

"admin",

389

"secure_password"

390

)

391

);

392

393

return dbConfig;

394

}

395

}

396

```

397

398

### Parameter Validation and Error Handling

399

400

Handle parameter-related errors and validation.

401

402

```javascript { .api }

403

/**

404

* Exception thrown when required parameter is not found

405

*/

406

class NoParameterFoundException extends Error {

407

constructor(message: string);

408

}

409

410

/**

411

* Exception thrown when parameter type doesn't match expected

412

*/

413

class DefinitionParameterException extends Error {

414

constructor(message: string);

415

}

416

```

417

418

**Usage Examples:**

419

420

```javascript

421

import {

422

module,

423

parametersOf,

424

NoParameterFoundException,

425

DefinitionParameterException

426

} from "koin-core";

427

428

const validatedModule = module((builder) => {

429

builder.factory((scope, params) => {

430

try {

431

// Validate required parameters

432

if (params.isEmpty()) {

433

throw new DefinitionParameterException("Database parameters required");

434

}

435

436

if (params.size() < 2) {

437

throw new DefinitionParameterException("Host and port parameters required");

438

}

439

440

const host = params.elementAt(0);

441

const port = params.elementAt(1);

442

443

// Type validation

444

if (typeof host !== 'string') {

445

throw new DefinitionParameterException("Host must be string");

446

}

447

448

if (typeof port !== 'number') {

449

throw new DefinitionParameterException("Port must be number");

450

}

451

452

return new DatabaseConnection(host, port);

453

454

} catch (error) {

455

if (error instanceof NoParameterFoundException) {

456

console.error("Missing required parameter:", error.message);

457

return new DatabaseConnection("localhost", 5432); // Default fallback

458

}

459

throw error;

460

}

461

});

462

});

463

464

// Safe parameter access

465

class SafeServiceManager extends KoinComponent {

466

async createConnection(host, port) {

467

try {

468

const connection = this.get(named("validated"), () =>

469

parametersOf(host, port)

470

);

471

return connection;

472

} catch (error) {

473

if (error instanceof DefinitionParameterException) {

474

console.error("Parameter validation failed:", error.message);

475

// Handle gracefully or re-throw

476

throw new Error(`Failed to create connection: ${error.message}`);

477

}

478

throw error;

479

}

480

}

481

}

482

```

483

484

## Types

485

486

```javascript { .api }

487

/** Function type for parameter definitions */

488

type ParametersDefinition = () => ParametersHolder;

489

490

/** Qualifier value type - can be any type */

491

type QualifierValue = any;

492

493

/** String-based qualifier implementation */

494

class StringQualifier implements Qualifier {

495

value: string;

496

constructor(name: string);

497

}

498

499

/** Type-based qualifier implementation */

500

class TypeQualifier implements Qualifier {

501

value: any;

502

constructor(type: any);

503

}

504

505

/** Parameter holder for dependency injection */

506

class ParametersHolder {

507

values(): any[];

508

elementAt<T>(index: number, clazz?: new (...args: any[]) => T): T;

509

get<T>(): T;

510

isEmpty(): boolean;

511

isNotEmpty(): boolean;

512

size(): number;

513

component1<T>(): T;

514

component2<T>(): T;

515

component3<T>(): T;

516

component4<T>(): T;

517

component5<T>(): T;

518

}

519

520

/** Exception for missing parameters */

521

class NoParameterFoundException extends Error {

522

constructor(message: string);

523

}

524

525

/** Exception for parameter definition errors */

526

class DefinitionParameterException extends Error {

527

constructor(message: string);

528

}

529

```