0
# Module DSL and Definition
1
2
The Koin DSL provides a declarative way to define dependency injection modules using Kotlin's DSL capabilities. Modules contain dependency definitions that specify how objects are created and managed.
3
4
## Core Module Creation
5
6
```kotlin { .api }
7
fun module(createdAtStart: Boolean = false, moduleDeclaration: ModuleDeclaration): Module
8
9
typealias ModuleDeclaration = Module.() -> Unit
10
```
11
12
The `module` function creates a new Koin module. The `createdAtStart` parameter determines if all singleton instances in this module should be created eagerly when the module is loaded.
13
14
### Usage Example
15
16
```kotlin
17
val myModule = module {
18
single<DatabaseService> { DatabaseServiceImpl() }
19
factory<UserRepository> { UserRepositoryImpl(get()) }
20
}
21
22
// Module with eager initialization
23
val eagerModule = module(createdAtStart = true) {
24
single<AppConfig> { AppConfigImpl() }
25
}
26
```
27
28
## Dependency Definition Types
29
30
### Single (Singleton)
31
32
Creates a single instance that is shared across the entire application lifecycle.
33
34
```kotlin { .api }
35
inline fun <reified T> Module.single(
36
qualifier: Qualifier? = null,
37
createdAtStart: Boolean = false,
38
noinline definition: Definition<T>
39
): KoinDefinition<T>
40
```
41
42
**Parameters:**
43
- `qualifier`: Optional qualifier to distinguish between multiple implementations
44
- `createdAtStart`: If true, creates the instance immediately when the module loads
45
- `definition`: Factory function that creates the instance
46
47
### Factory
48
49
Creates a new instance each time it's requested.
50
51
```kotlin { .api }
52
inline fun <reified T> Module.factory(
53
qualifier: Qualifier? = null,
54
noinline definition: Definition<T>
55
): KoinDefinition<T>
56
```
57
58
**Parameters:**
59
- `qualifier`: Optional qualifier to distinguish between multiple implementations
60
- `definition`: Factory function that creates the instance
61
62
### Scoped
63
64
Creates instances that are tied to a specific scope lifecycle.
65
66
```kotlin { .api }
67
inline fun <reified T> ScopeDSL.scoped(
68
qualifier: Qualifier? = null,
69
noinline definition: Definition<T>
70
): KoinDefinition<T>
71
```
72
73
## Constructor-Based DSL Functions
74
75
Koin provides constructor-based DSL functions that offer a more direct way to declare dependencies using constructor references.
76
77
### SingleOf
78
79
Creates a singleton instance using a constructor reference.
80
81
```kotlin { .api }
82
inline fun <reified R> Module.singleOf(
83
crossinline constructor: () -> R,
84
noinline options: DefinitionOptions<R>? = null
85
): KoinDefinition<R>
86
87
inline fun <reified R, reified T1> Module.singleOf(
88
crossinline constructor: (T1) -> R,
89
noinline options: DefinitionOptions<R>? = null
90
): KoinDefinition<R>
91
92
inline fun <reified R, reified T1, reified T2> Module.singleOf(
93
crossinline constructor: (T1, T2) -> R,
94
noinline options: DefinitionOptions<R>? = null
95
): KoinDefinition<R>
96
97
// Additional overloads for more parameters...
98
```
99
100
### FactoryOf
101
102
Creates a factory instance using a constructor reference.
103
104
```kotlin { .api }
105
inline fun <reified R> Module.factoryOf(
106
crossinline constructor: () -> R,
107
noinline options: DefinitionOptions<R>? = null
108
): KoinDefinition<R>
109
110
inline fun <reified R, reified T1> Module.factoryOf(
111
crossinline constructor: (T1) -> R,
112
noinline options: DefinitionOptions<R>? = null
113
): KoinDefinition<R>
114
115
inline fun <reified R, reified T1, reified T2> Module.factoryOf(
116
crossinline constructor: (T1, T2) -> R,
117
noinline options: DefinitionOptions<R>? = null
118
): KoinDefinition<R>
119
120
// Additional overloads for more parameters...
121
```
122
123
### ScopedOf
124
125
Creates a scoped instance using a constructor reference.
126
127
```kotlin { .api }
128
inline fun <reified R> ScopeDSL.scopedOf(
129
crossinline constructor: () -> R,
130
noinline options: DefinitionOptions<R>? = null
131
): KoinDefinition<R>
132
133
inline fun <reified R, reified T1> ScopeDSL.scopedOf(
134
crossinline constructor: (T1) -> R,
135
noinline options: DefinitionOptions<R>? = null
136
): KoinDefinition<R>
137
138
inline fun <reified R, reified T1, reified T2> ScopeDSL.scopedOf(
139
crossinline constructor: (T1, T2) -> R,
140
noinline options: DefinitionOptions<R>? = null
141
): KoinDefinition<R>
142
143
// Additional overloads for more parameters...
144
```
145
146
### Constructor-Based Usage Examples
147
148
```kotlin
149
val myModule = module {
150
// Using constructor references instead of lambdas
151
singleOf(::DatabaseServiceImpl)
152
factoryOf(::UserRepositoryImpl)
153
154
// With multiple dependencies
155
singleOf(::UserServiceImpl) // constructor takes DatabaseService, UserRepository
156
157
scope<UserSession> {
158
scopedOf(::SessionDataImpl)
159
scopedOf(::UserPreferencesImpl)
160
}
161
}
162
163
// Equivalent to:
164
val traditionalModule = module {
165
single<DatabaseServiceImpl> { DatabaseServiceImpl() }
166
factory<UserRepositoryImpl> { UserRepositoryImpl() }
167
single<UserServiceImpl> { UserServiceImpl(get(), get()) }
168
169
scope<UserSession> {
170
scoped<SessionDataImpl> { SessionDataImpl() }
171
scoped<UserPreferencesImpl> { UserPreferencesImpl() }
172
}
173
}
174
```
175
176
## Definition Function
177
178
```kotlin { .api }
179
typealias Definition<T> = Scope.(ParametersDefinition?) -> T
180
```
181
182
The definition function is a lambda that creates instances. It receives:
183
- `Scope`: The current scope for resolving dependencies
184
- `ParametersDefinition?`: Optional parameters passed during injection
185
186
### Dependency Resolution
187
188
Within definition functions, use `get()` to resolve dependencies:
189
190
```kotlin
191
val myModule = module {
192
single<Database> { DatabaseImpl() }
193
single<UserService> { UserServiceImpl(get<Database>()) }
194
195
// With qualifier
196
single<Cache>(named("user-cache")) { UserCacheImpl() }
197
single<UserRepository> {
198
UserRepositoryImpl(get<Database>(), get<Cache>(named("user-cache")))
199
}
200
}
201
```
202
203
## Scope Definition
204
205
```kotlin { .api }
206
fun Module.scope(qualifier: Qualifier, scopeSet: ScopeDSL.() -> Unit)
207
208
inline fun <reified T> Module.scope(scopeSet: ScopeDSL.() -> Unit)
209
```
210
211
Scopes group dependencies with a shared lifecycle:
212
213
```kotlin
214
val myModule = module {
215
scope<UserSession> {
216
scoped<SessionData> { SessionDataImpl() }
217
scoped<UserPreferences> { UserPreferencesImpl(get()) }
218
}
219
220
// Named scope
221
scope(named("http-client")) {
222
scoped<HttpClient> { HttpClientImpl() }
223
scoped<ApiService> { ApiServiceImpl(get()) }
224
}
225
}
226
```
227
228
## Qualifiers
229
230
Qualifiers distinguish between multiple implementations of the same type.
231
232
```kotlin { .api }
233
interface Qualifier {
234
val value: String
235
}
236
237
class StringQualifier(override val value: String) : Qualifier
238
class TypeQualifier(val kclass: KClass<*>) : Qualifier
239
240
fun named(name: String): StringQualifier
241
```
242
243
### Usage Examples
244
245
```kotlin
246
val myModule = module {
247
// Multiple implementations with qualifiers
248
single<Database>(named("primary")) { PrimaryDatabaseImpl() }
249
single<Database>(named("cache")) { CacheDatabaseImpl() }
250
251
// Type-based qualifier
252
single<Logger>(qualifier<ConsoleLogger>()) { ConsoleLoggerImpl() }
253
single<Logger>(qualifier<FileLogger>()) { FileLoggerImpl() }
254
}
255
```
256
257
## KoinDefinition Extensions
258
259
```kotlin { .api }
260
class KoinDefinition<T>(val module: Module, val beanDefinition: BeanDefinition<T>) {
261
inline fun <reified Type> bind(): KoinDefinition<T>
262
fun createdAtStart(): BeanDefinition<T>
263
}
264
```
265
266
The `KoinDefinition` class allows chaining additional configuration:
267
268
```kotlin
269
val myModule = module {
270
single<UserServiceImpl> { UserServiceImpl(get()) }
271
.bind<UserService>() // Bind to interface
272
.bind<Auditable>() // Bind to additional interface
273
274
single<DatabaseService> { DatabaseServiceImpl() }
275
.createdAtStart() // Create eagerly
276
}
277
```
278
279
## Module Composition
280
281
```kotlin { .api }
282
fun Module.includes(vararg module: Module)
283
fun Module.includes(module: Collection<Module>)
284
285
operator fun Module.plus(module: Module): List<Module>
286
operator fun Module.plus(modules: List<Module>): List<Module>
287
```
288
289
Combine modules for better organization:
290
291
```kotlin
292
val databaseModule = module {
293
single<Database> { DatabaseImpl() }
294
}
295
296
val serviceModule = module {
297
includes(databaseModule)
298
single<UserService> { UserServiceImpl(get()) }
299
}
300
301
// Using operators
302
val allModules = databaseModule + serviceModule
303
```
304
305
## Advanced Features
306
307
### Parameters
308
309
Pass parameters during injection:
310
311
```kotlin
312
val myModule = module {
313
factory<UserService> { params ->
314
val userId = params.get<String>()
315
UserServiceImpl(userId, get())
316
}
317
}
318
319
// Usage
320
val userService = get<UserService> { parametersOf("user123") }
321
```
322
323
### Conditional Definition
324
325
```kotlin
326
val myModule = module {
327
single<Logger> {
328
if (BuildConfig.DEBUG) {
329
ConsoleLogger()
330
} else {
331
FileLogger()
332
}
333
}
334
}
335
```