Skip to content

Commit 4cb4496

Browse files
committed
KTLN-841: add annotated koin scopes example
Also downgrade koin and kotlin to stable version as release candidate version seem to be break scope annotations
1 parent 394a523 commit 4cb4496

File tree

2 files changed

+159
-4
lines changed

2 files changed

+159
-4
lines changed

koin-guide/koin-annotations/build.gradle.kts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
group = "com.baeldung"
22
version = "1.0-SNAPSHOT"
33

4-
val koinVersion = "4.0.0-RC1"
5-
val koinAnnotationsVersion = "1.4.0-RC3"
4+
val koinVersion = "3.5.6"
5+
val koinAnnotationsVersion = "1.3.1"
66

77
repositories {
88
mavenCentral()
99
}
1010

1111
plugins {
12-
kotlin("jvm") version "2.0.10"
13-
id("com.google.devtools.ksp") version "2.0.10-1.0.24"
12+
kotlin("jvm") version "1.9.24"
13+
id("com.google.devtools.ksp") version "1.9.24-1.0.20"
1414
}
1515

1616
dependencies {
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package com.baeldung.kotlin.koin.annotations
2+
3+
import org.koin.core.annotation.Module
4+
import org.koin.core.annotation.Scope
5+
import org.koin.core.annotation.Single
6+
import org.koin.core.context.startKoin
7+
import org.koin.core.error.NoDefinitionFoundException
8+
import org.koin.core.error.ScopeNotCreatedException
9+
import org.koin.core.parameter.ParametersHolder
10+
import org.koin.core.parameter.parametersOf
11+
import org.koin.java.KoinJavaComponent.getKoin
12+
import org.koin.ksp.generated.defaultModule
13+
import org.koin.ksp.generated.module
14+
15+
class ShoppingCart {
16+
17+
private val items = mutableListOf<Int>()
18+
19+
fun addItem(itemId: Int) {
20+
items.add(itemId)
21+
}
22+
23+
fun getItemIds(): List<Int> = items
24+
25+
fun clearCart() {
26+
items.clear()
27+
}
28+
}
29+
30+
class Checkout(private val shoppingCart: ShoppingCart) {
31+
32+
private var paid = false
33+
34+
fun confirm() {
35+
// Business logic with shopping cart
36+
paid = true
37+
println("Successfully paid for items")
38+
}
39+
}
40+
41+
class ShoppingService {
42+
43+
private val koin = getKoin()
44+
45+
fun startShopping(userId: String) {
46+
koin.createScope<ShoppingSessionScope>(scopeId = "shopping-$userId")
47+
}
48+
49+
fun addItem(userId: String, itemId: Int) {
50+
val shoppingScope = koin.getScope(scopeId = "shopping-$userId")
51+
val cart = shoppingScope.get<ShoppingCart>()
52+
53+
// Add items to the cart during the session
54+
cart.addItem(itemId)
55+
56+
// Business logic with the cart
57+
println("Items in cart: ${cart.getItemIds()}")
58+
}
59+
60+
fun checkoutAndEndShopping(userId: String) {
61+
// Clean up the scope when shopping ends
62+
val shoppingScope = koin.getScope(scopeId = "shopping-$userId")
63+
val cart = shoppingScope.get<ShoppingCart>()
64+
65+
val checkoutScope = koin.createScope<CheckoutSessionScope>(
66+
scopeId = "checkout-$userId",
67+
// Register a scope parameter
68+
parametersOf(cart)
69+
)
70+
71+
val checkout = checkoutScope.get<Checkout> {
72+
parametersOf(
73+
// Access scope's parameters
74+
checkoutScope.getSource<ParametersHolder>()!!.get<ShoppingCart>()
75+
)
76+
}
77+
78+
checkout.confirm()
79+
cart.clearCart()
80+
81+
shoppingScope.close()
82+
checkoutScope.close()
83+
}
84+
}
85+
86+
class ShoppingSessionScope
87+
class CheckoutSessionScope
88+
89+
@Module
90+
class ShoppingModule {
91+
92+
@Single
93+
fun provideShoppingService() = ShoppingService()
94+
95+
@Scope(ShoppingSessionScope::class)
96+
fun provideShoppingCart() = ShoppingCart()
97+
98+
@Scope(CheckoutSessionScope::class)
99+
fun provideCheckout(shoppingCart: ShoppingCart) = Checkout(shoppingCart)
100+
}
101+
102+
object KoinScopesApplication {
103+
104+
@JvmStatic
105+
fun main(args: Array<String>) {
106+
107+
val koinApp = startKoin {
108+
printLogger()
109+
modules(
110+
ShoppingModule().module,
111+
defaultModule
112+
)
113+
}
114+
115+
// Shopping cart is scoped, no global bean exists
116+
try {
117+
koinApp.koin.get<ShoppingCart>()
118+
} catch (e: Exception) {
119+
require(e is NoDefinitionFoundException)
120+
}
121+
122+
val service = koinApp.koin.get<ShoppingService>()
123+
124+
val shoppingUserId = "platform-user"
125+
// Shopping scope is not yet initialized for user
126+
try {
127+
koinApp.koin.getScope(scopeId = "shopping-$shoppingUserId")
128+
} catch (e: Exception) {
129+
require(e is ScopeNotCreatedException)
130+
}
131+
132+
// Shopping scope is created with empty cart
133+
service.startShopping(shoppingUserId)
134+
135+
val shoppingUserSession = koinApp.koin.getScope(scopeId = "shopping-$shoppingUserId")
136+
val shoppingUserCart = shoppingUserSession.get<ShoppingCart>()
137+
138+
require(shoppingUserCart.getItemIds().isEmpty())
139+
140+
// User adds an item to its shopping cart
141+
val addedItemId = 1
142+
service.addItem(shoppingUserId, addedItemId)
143+
144+
require(shoppingUserCart.getItemIds().contains(addedItemId))
145+
146+
// Shopping scope is ended and removed from memory
147+
service.checkoutAndEndShopping(shoppingUserId)
148+
149+
try {
150+
koinApp.koin.getScope(scopeId = "shopping-$shoppingUserId")
151+
} catch (e: Exception) {
152+
require(e is ScopeNotCreatedException)
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)