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

dependency-injection.mddocs/

0

# Dependency Resolution and Injection

1

2

Core dependency injection functionality for retrieving instances, lazy injection, parameter passing, and component-based dependency access.

3

4

## Capabilities

5

6

### Core Dependency Resolution

7

8

Get instances from the Koin container with type safety and parameter injection.

9

10

```javascript { .api }

11

class Koin {

12

/**

13

* Get instance of type T from the container

14

* @param qualifier - Optional qualifier for specific instance

15

* @param parameters - Optional parameters for instance creation

16

* @returns Instance of type T

17

* @throws NoDefinitionFoundException if definition not found

18

*/

19

get<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T;

20

get<T>(clazz: any, qualifier?: Qualifier, parameters?: ParametersDefinition): T;

21

22

/**

23

* Get instance or null if not found - safe alternative to get()

24

* @param qualifier - Optional qualifier for specific instance

25

* @param parameters - Optional parameters for instance creation

26

* @returns Instance of type T or null if not found

27

*/

28

getOrNull<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T | null;

29

getOrNull<T>(clazz: any, qualifier?: Qualifier, parameters?: ParametersDefinition): T | null;

30

31

/**

32

* Lazy injection - resolved on first access

33

* @param qualifier - Optional qualifier for specific instance

34

* @param mode - Thread safety mode for lazy initialization (default: SYNCHRONIZED)

35

* @param parameters - Optional parameters for instance creation

36

* @returns Lazy<T> wrapper that resolves on first access

37

*/

38

inject<T>(

39

qualifier?: Qualifier,

40

mode?: LazyThreadSafetyMode,

41

parameters?: ParametersDefinition

42

): Lazy<T>;

43

44

/**

45

* Lazy injection that can return null if not found

46

* @param qualifier - Optional qualifier for specific instance

47

* @param mode - Thread safety mode for lazy initialization (default: SYNCHRONIZED)

48

* @param parameters - Optional parameters for instance creation

49

* @returns Lazy<T | null> wrapper that resolves on first access

50

*/

51

injectOrNull<T>(

52

qualifier?: Qualifier,

53

mode?: LazyThreadSafetyMode,

54

parameters?: ParametersDefinition

55

): Lazy<T | null>;

56

57

/**

58

* Get all instances of type T from the container

59

* @returns Array of all instances matching type T

60

*/

61

getAll<T>(): T[];

62

63

/**

64

* Declare existing instance in container for injection

65

* @param instance - Instance to declare

66

* @param qualifier - Optional qualifier for identification

67

* @param secondaryTypes - Additional types to bind

68

* @param allowOverride - Whether to allow overriding existing definition

69

*/

70

declare<T>(

71

instance: T,

72

qualifier?: Qualifier,

73

secondaryTypes?: any[],

74

allowOverride?: boolean

75

): void;

76

}

77

```

78

79

**Usage Examples:**

80

81

```javascript

82

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

83

84

// Setup

85

const appModule = module((builder) => {

86

builder.single(() => new DatabaseService("localhost:5432"));

87

builder.factory(() => new ApiClient());

88

builder.single("cache", () => new CacheService());

89

});

90

91

startKoin((app) => app.modules([appModule]));

92

93

// Get Koin instance

94

const koin = GlobalContext.get();

95

96

// Basic instance retrieval

97

const database = koin.get(); // DatabaseService

98

const apiClient = koin.get(); // ApiClient (new instance each time)

99

100

// Qualified instance retrieval

101

const cache = koin.get("cache"); // CacheService

102

103

// Safe retrieval

104

const optionalService = koin.getOrNull(); // Service | null

105

106

// With parameters

107

const userService = koin.get(null, () => parametersOf("user123", true));

108

109

// Get all instances of a type

110

const allHandlers = koin.getAll(); // MessageHandler[]

111

112

// Declare runtime instance

113

const runtimeService = new RuntimeService();

114

koin.declare(runtimeService, "runtime");

115

```

116

117

### Component-Based Injection

118

119

Use the KoinComponent interface to add dependency injection capabilities to your classes.

120

121

```javascript { .api }

122

interface KoinComponent {

123

/**

124

* Get the Koin container instance

125

* @returns Koin container for dependency resolution

126

*/

127

getKoin(): Koin;

128

}

129

130

// Extension functions for KoinComponent

131

/**

132

* Get dependency instance from component

133

* @param qualifier - Optional qualifier for specific instance

134

* @param parameters - Optional parameters for instance creation

135

* @returns Instance of type T

136

*/

137

function get<T>(

138

this: KoinComponent,

139

qualifier?: Qualifier,

140

parameters?: () => ParametersHolder

141

): T;

142

143

/**

144

* Lazy dependency injection for component

145

* @param qualifier - Optional qualifier for specific instance

146

* @param mode - Thread safety mode for lazy initialization

147

* @param parameters - Optional parameters for instance creation

148

* @returns Lazy<T> wrapper that resolves on first access

149

*/

150

function inject<T>(

151

this: KoinComponent,

152

qualifier?: Qualifier,

153

mode?: LazyThreadSafetyMode,

154

parameters?: () => ParametersHolder

155

): Lazy<T>;

156

```

157

158

**Usage Examples:**

159

160

```javascript

161

import { KoinComponent } from "koin-core";

162

163

class UserController extends KoinComponent {

164

constructor() {

165

super();

166

// Direct injection

167

this.userService = this.get(); // UserService

168

this.logger = this.get("console"); // ConsoleLogger

169

170

// Lazy injection - resolved on first access

171

this.cacheLazy = this.inject(); // Lazy<CacheService>

172

this.apiClientLazy = this.inject("external"); // Lazy<ExternalApiClient>

173

}

174

175

async getUser(id) {

176

// Access lazy dependencies

177

const cache = this.cacheLazy.value;

178

const apiClient = this.apiClientLazy.value;

179

180

// Use injected dependencies

181

this.logger.info(`Getting user ${id}`);

182

return await this.userService.findById(id);

183

}

184

}

185

186

// Alternative implementation using composition

187

class ProductService {

188

constructor() {

189

this.koinComponent = new KoinComponent();

190

this.database = this.koinComponent.get(); // DatabaseService

191

this.validator = this.koinComponent.get("product"); // ProductValidator

192

}

193

}

194

```

195

196

### Property Injection

197

198

Inject configuration properties and runtime values.

199

200

```javascript { .api }

201

class Koin {

202

/**

203

* Get property value by key

204

* @param key - Property key

205

* @param defaultValue - Default value if property not found

206

* @returns Property value of type T

207

*/

208

getProperty<T>(key: string, defaultValue?: T): T;

209

210

/**

211

* Get property value or null if not found

212

* @param key - Property key

213

* @returns Property value or null

214

*/

215

getPropertyOrNull<T>(key: string): T | null;

216

217

/**

218

* Set property value

219

* @param key - Property key

220

* @param value - Property value

221

*/

222

setProperty(key: string, value: any): void;

223

224

/**

225

* Delete property by key

226

* @param key - Property key

227

*/

228

deleteProperty(key: string): void;

229

}

230

231

// Extension functions for KoinComponent

232

/**

233

* Get property from component context

234

* @param key - Property key

235

* @param defaultValue - Default value if property not found

236

* @returns Property value

237

*/

238

function getProperty<T>(

239

this: KoinComponent,

240

key: string,

241

defaultValue?: T

242

): T;

243

```

244

245

**Usage Examples:**

246

247

```javascript

248

import { startKoin, module, KoinComponent } from "koin-core";

249

250

// Setup with properties

251

startKoin((app) => {

252

app.modules([appModule]);

253

app.properties(new Map([

254

["database.url", "mongodb://localhost:27017"],

255

["api.timeout", 5000],

256

["debug.enabled", true]

257

]));

258

});

259

260

class DatabaseService extends KoinComponent {

261

constructor() {

262

super();

263

// Inject properties with defaults

264

this.url = this.getProperty("database.url", "mongodb://localhost:27017");

265

this.timeout = this.getProperty("api.timeout", 3000);

266

this.debugEnabled = this.getProperty("debug.enabled", false);

267

}

268

}

269

270

// Direct property access

271

const koin = GlobalContext.get();

272

const apiUrl = koin.getProperty("api.url", "https://api.default.com");

273

const debugMode = koin.getPropertyOrNull("debug.mode"); // boolean | null

274

275

// Runtime property updates

276

koin.setProperty("cache.ttl", 300);

277

koin.deleteProperty("temp.flag");

278

```

279

280

### Parameter-Based Injection

281

282

Pass parameters during dependency resolution for dynamic instance creation.

283

284

```javascript { .api }

285

/**

286

* Create parameters holder for injection

287

* @param parameters - Parameter values in order

288

* @returns ParametersHolder with indexed access

289

*/

290

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

291

292

/**

293

* Create indexed parameter array

294

* @param parameters - Parameter values

295

* @returns ParametersHolder with array-like access

296

*/

297

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

298

299

/**

300

* Create parameter set for type-based access

301

* @param parameters - Parameter values

302

* @returns ParametersHolder with type-based access

303

*/

304

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

305

306

/**

307

* Create empty parameters holder

308

* @returns Empty ParametersHolder

309

*/

310

function emptyParametersHolder(): ParametersHolder;

311

312

class ParametersHolder {

313

/**

314

* Get parameter by index and expected type

315

* @param index - Parameter index

316

* @param clazz - Expected parameter type

317

* @returns Parameter value of type T

318

*/

319

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

320

321

/**

322

* Get parameter by type (first matching type)

323

* @returns Parameter value of type T

324

*/

325

get<T>(): T;

326

327

/**

328

* Check if parameters are empty

329

* @returns true if no parameters

330

*/

331

isEmpty(): boolean;

332

333

/**

334

* Check if parameters exist

335

* @returns true if parameters exist

336

*/

337

isNotEmpty(): boolean;

338

339

/**

340

* Get parameter count

341

* @returns Number of parameters

342

*/

343

size(): number;

344

345

/**

346

* Destructuring support - get first parameter

347

* @returns First parameter

348

*/

349

component1<T>(): T;

350

351

/**

352

* Destructuring support - get second parameter

353

* @returns Second parameter

354

*/

355

component2<T>(): T;

356

357

/**

358

* Destructuring support - get third parameter

359

* @returns Third parameter

360

*/

361

component3<T>(): T;

362

363

/**

364

* Destructuring support - get fourth parameter

365

* @returns Fourth parameter

366

*/

367

component4<T>(): T;

368

369

/**

370

* Destructuring support - get fifth parameter

371

* @returns Fifth parameter

372

*/

373

component5<T>(): T;

374

}

375

```

376

377

**Usage Examples:**

378

379

```javascript

380

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

381

382

// Module with parameter-accepting definitions

383

const userModule = module((builder) => {

384

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

385

const userId = params.get(); // string

386

const includeProfile = params.elementAt(1); // boolean

387

return new UserService(userId, includeProfile);

388

});

389

390

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

391

const [host, port, database] = params.component1(), params.component2(), params.component3();

392

return new DatabaseConnection(host, port, database);

393

});

394

});

395

396

class UserController extends KoinComponent {

397

async getUser(userId, includeProfile = false) {

398

// Pass parameters during injection

399

const userService = this.get(null, () =>

400

parametersOf(userId, includeProfile)

401

);

402

403

return await userService.getUser();

404

}

405

406

async connectToDatabase() {

407

// Multiple parameters

408

const dbConnection = this.get(null, () =>

409

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

410

);

411

412

return dbConnection.connect();

413

}

414

}

415

416

// Different parameter creation methods

417

const indexedParams = parametersOf("value1", 42, true);

418

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

419

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

420

const emptyParams = emptyParametersHolder();

421

```

422

423

### Lazy Injection

424

425

Defer dependency resolution until first access for performance optimization.

426

427

```javascript { .api }

428

interface Lazy<T> {

429

/**

430

* Get the lazily resolved value - resolved on first access

431

*/

432

value: T;

433

}

434

435

/**

436

* Thread safety modes for lazy initialization

437

*/

438

enum LazyThreadSafetyMode {

439

/** Thread-safe lazy initialization */

440

SYNCHRONIZED = "SYNCHRONIZED",

441

/** Not thread-safe but faster */

442

NONE = "NONE",

443

/** Thread-safe with publication safety */

444

PUBLICATION = "PUBLICATION"

445

}

446

```

447

448

**Usage Examples:**

449

450

```javascript

451

import { KoinComponent, LazyThreadSafetyMode } from "koin-core";

452

453

class ApplicationService extends KoinComponent {

454

constructor() {

455

super();

456

457

// Lazy dependencies - resolved on first access

458

this.expensiveService = this.inject(); // Lazy<ExpensiveService>

459

this.cacheService = this.inject("redis"); // Lazy<RedisCache>

460

461

// Thread-safe lazy with specific mode

462

this.sharedResource = this.inject(

463

"shared",

464

LazyThreadSafetyMode.SYNCHRONIZED

465

); // Lazy<SharedResource>

466

}

467

468

async processData(data) {

469

// Services are created only when first accessed

470

const expensive = this.expensiveService.value; // Created here if not already

471

const cache = this.cacheService.value; // Created here if not already

472

473

// Subsequent access uses cached instance

474

const cachedResult = this.cacheService.value.get("result");

475

476

return await expensive.process(data);

477

}

478

}

479

480

// Manual lazy injection

481

const koin = GlobalContext.get();

482

const lazyLogger = koin.inject("file"); // Lazy<FileLogger>

483

484

// Access when needed

485

function logMessage(message) {

486

const logger = lazyLogger.value; // Created on first access

487

logger.log(message);

488

}

489

```

490

491

## Types

492

493

```javascript { .api }

494

/** Function type for parameter definitions */

495

type ParametersDefinition = () => ParametersHolder;

496

497

/** Thread safety modes for lazy initialization */

498

enum LazyThreadSafetyMode {

499

SYNCHRONIZED = "SYNCHRONIZED",

500

NONE = "NONE",

501

PUBLICATION = "PUBLICATION"

502

}

503

504

/** Lazy wrapper interface */

505

interface Lazy<T> {

506

value: T;

507

}

508

509

/** Exception thrown when definition is not found */

510

class NoDefinitionFoundException extends Error {

511

constructor(message: string);

512

}

513

514

/** Exception thrown when instance creation fails */

515

class InstanceCreationException extends Error {

516

constructor(message: string, cause?: Error);

517

}

518

519

/** Exception thrown when required parameter is not found */

520

class NoParameterFoundException extends Error {

521

constructor(message: string);

522

}

523

```