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