0
# Component Integration
1
2
Koin provides the `KoinComponent` interface and extension functions to integrate dependency injection into your Kotlin classes. This allows any class to participate in the Koin dependency injection system.
3
4
## KoinComponent Interface
5
6
```kotlin { .api }
7
interface KoinComponent {
8
fun getKoin(): Koin
9
}
10
```
11
12
The `KoinComponent` interface is a marker interface that provides access to the Koin instance. Any class implementing this interface can use Koin's dependency injection features.
13
14
### Basic Usage
15
16
```kotlin
17
class UserController : KoinComponent {
18
private val userService: UserService = get()
19
20
fun createUser(userData: UserData) {
21
userService.create(userData)
22
}
23
}
24
```
25
26
## Dependency Injection Methods
27
28
### get() - Direct Injection
29
30
```kotlin { .api }
31
inline fun <reified T : Any> KoinComponent.get(
32
qualifier: Qualifier? = null,
33
noinline parameters: ParametersDefinition? = null
34
): T
35
```
36
37
Immediately resolves and returns an instance of the requested type.
38
39
**Parameters:**
40
- `qualifier`: Optional qualifier to distinguish between multiple implementations
41
- `parameters`: Optional parameters to pass to the definition function
42
43
### inject() - Lazy Injection
44
45
```kotlin { .api }
46
inline fun <reified T : Any> KoinComponent.inject(
47
qualifier: Qualifier? = null,
48
mode: LazyThreadSafetyMode = KoinPlatformTools.defaultLazyMode(),
49
noinline parameters: ParametersDefinition? = null
50
): Lazy<T>
51
```
52
53
Returns a lazy delegate that resolves the instance on first access.
54
55
**Parameters:**
56
- `qualifier`: Optional qualifier to distinguish between multiple implementations
57
- `mode`: Lazy thread safety mode (platform-specific default)
58
- `parameters`: Optional parameters to pass to the definition function
59
60
### Usage Examples
61
62
```kotlin
63
class OrderService : KoinComponent {
64
// Direct injection - resolved immediately
65
private val database: Database = get()
66
67
// Lazy injection - resolved on first access
68
private val emailService: EmailService by inject()
69
70
// With qualifiers
71
private val primaryCache: Cache = get(named("primary"))
72
private val secondaryCache: Cache by inject(named("secondary"))
73
74
// With parameters
75
private fun getValidator(type: String): Validator {
76
return get { parametersOf(type) }
77
}
78
}
79
```
80
81
## KoinScopeComponent Interface
82
83
```kotlin { .api }
84
interface KoinScopeComponent : KoinComponent {
85
val scope: Scope
86
}
87
```
88
89
`KoinScopeComponent` extends `KoinComponent` to provide scoped dependency injection. Classes implementing this interface have their own scope for managing lifecycle-aware dependencies.
90
91
### Scope Management Functions
92
93
```kotlin { .api }
94
fun <T : Any> T.getScopeId(): ScopeID
95
fun <T : Any> T.getScopeName(): TypeQualifier
96
97
fun <T : KoinScopeComponent> T.createScope(
98
scopeId: ScopeID = getScopeId(),
99
source: Any? = null,
100
scopeArchetype: TypeQualifier? = null
101
): Scope
102
103
fun <T : KoinScopeComponent> T.createScope(source: Any? = null): Scope
104
fun <T : KoinScopeComponent> T.getScopeOrNull(): Scope?
105
```
106
107
### Usage Example
108
109
```kotlin
110
class UserSession : KoinScopeComponent {
111
override val scope: Scope = createScope()
112
113
// Inject from the component's scope
114
private val sessionData: SessionData by scope.inject()
115
private val userPreferences: UserPreferences = scope.get()
116
117
fun logout() {
118
// Clean up scoped dependencies
119
scope.close()
120
}
121
}
122
```
123
124
## Integration Patterns
125
126
### Property Injection
127
128
```kotlin
129
class MyService : KoinComponent {
130
// Lazy properties
131
private val repository by inject<UserRepository>()
132
private val config by inject<AppConfig>()
133
private val logger by inject<Logger>(named("service"))
134
135
fun doWork() {
136
logger.info("Starting work")
137
val users = repository.findAll()
138
// ...
139
}
140
}
141
```
142
143
### Constructor Injection Alternative
144
145
While Koin primarily uses property injection, you can also resolve dependencies in constructors:
146
147
```kotlin
148
class MyService : KoinComponent {
149
private val repository: UserRepository
150
private val config: AppConfig
151
152
init {
153
repository = get()
154
config = get()
155
}
156
}
157
```
158
159
### Conditional Injection
160
161
```kotlin
162
class MyService : KoinComponent {
163
private val logger: Logger by lazy {
164
if (BuildConfig.DEBUG) {
165
get<Logger>(named("debug"))
166
} else {
167
get<Logger>(named("production"))
168
}
169
}
170
}
171
```
172
173
## Parameter Handling
174
175
### ParametersHolder
176
177
```kotlin { .api }
178
class ParametersHolder(private val values: Array<out Any?>) {
179
inline fun <reified T> get(index: Int = 0): T
180
inline fun <reified T> getOrNull(index: Int = 0): T?
181
fun size(): Int
182
}
183
184
fun parametersOf(vararg values: Any?): ParametersHolder
185
```
186
187
### Using Parameters
188
189
```kotlin
190
class DocumentService : KoinComponent {
191
fun processDocument(documentType: String, metadata: Map<String, Any>) {
192
val processor: DocumentProcessor = get {
193
parametersOf(documentType, metadata)
194
}
195
processor.process()
196
}
197
}
198
199
// In module definition
200
val documentModule = module {
201
factory<DocumentProcessor> { params ->
202
val type = params.get<String>(0)
203
val metadata = params.get<Map<String, Any>>(1)
204
when (type) {
205
"pdf" -> PDFProcessor(metadata)
206
"word" -> WordProcessor(metadata)
207
else -> GenericProcessor(metadata)
208
}
209
}
210
}
211
```
212
213
## Error Handling
214
215
Common exceptions when using components:
216
217
```kotlin { .api }
218
class NoBeanDefFoundException(message: String) : RuntimeException(message)
219
class InstanceCreationException(message: String, cause: Throwable?) : RuntimeException(message, cause)
220
class ClosedScopeException(message: String) : RuntimeException(message)
221
```
222
223
### Safe Injection
224
225
```kotlin
226
class MyService : KoinComponent {
227
fun safeGetService(): UserService? {
228
return try {
229
get<UserService>()
230
} catch (e: NoBeanDefFoundException) {
231
null
232
}
233
}
234
}
235
```
236
237
## Testing with Components
238
239
```kotlin
240
class UserControllerTest : KoinComponent {
241
242
@Before
243
fun setup() {
244
startKoin {
245
modules(testModule)
246
}
247
}
248
249
@Test
250
fun testUserCreation() {
251
val controller = UserController()
252
// Controller will use test dependencies
253
controller.createUser(testUserData)
254
}
255
256
@After
257
fun teardown() {
258
stopKoin()
259
}
260
}
261
```