SlideShare a Scribd company logo
Dependency Injections in
Kotlin
Problem Statement
How to do DI in a perfect world?
Problem Statement
public class SomeController {
public final BusinessLogic logic;
public SomeController(BusinessLogic logic) {
this.logic = logic;
}
public void callMe() {
//some stuff
logic.doSomeStuff();
//some other stuff
}
}
Problem Statement
public class SomeController {
public final BusinessLogic logic;
public SomeController(BusinessLogic logic) {
this.logic = logic;
}
public void callMe() {
//some stuff
logic.doSomeStuff();
//some other stuff
}
}
Problem Statement
How to do DI in perfect Java world?
Problem Statement
public class SomeController {
public final BusinessLogic logic;
@Inject
public SomeController(BusinessLogic logic) {
this.logic = logic;
}
public void callMe() {
//some stuff
logic.doSomeStuff();
//some other stuff
}
}
Problem Statement
public class SomeController {
public final BusinessLogic logic;
@Inject
public SomeController(BusinessLogic logic) {
this.logic = logic;
}
public void callMe() {
//some stuff
logic.doSomeStuff();
//some other stuff
}
}
Problem Statement
How to do DI in a real Android world? (until ActivityFactory)
Problem Statement
public class SomeActivity extends Activity {
@Inject
public BusinessLogic logic;
@Override
public void onCreate() {
//some code
Injector injector = getMyCoolInjector(this);
injector.inject(this);
//some code
}
}
Problem Statement
public class SomeActivity extends Activity {
@Inject
public BusinessLogic logic;
@Override
public void onCreate() {
//some code
Injector injector = getMyCoolInjector(this);
injector.inject(this);
//some code
}
}
Problem Statement
● Not final anymore
● SomeActivity should know about Injector implementation
● Testing is hard (because of p.2)
● Looks ugly
Dagger 2
Field Injections
@Inject
lateinit var feedViewModel:FeedViewModel
@Inject
@field:DatabaseInfo
@JvmField
var dbVersion: Int = -1
Field Injections
@Inject
lateinit var feedViewModel:FeedViewModel
@Inject
@field:DatabaseInfo
@JvmField
var dbVersion: Int = -1
Field Injections
@Inject
lateinit var feedViewModel:FeedViewModel
@Inject
@field:DatabaseInfo
@JvmField
var dbVersion: Int = -1
Field Injections
@Inject
lateinit var feedViewModel:FeedViewModel
@Inject
@field:DatabaseInfo
@JvmField
var dbVersion: Int = -1
Dagger 2 Summary
● Good for migration from Java
● Everybody know it
● The fastest DI ever (probably)
● Oldschool
Problem Statement
What if we will be able to initialize immutable variables not only in the constructor?
Problem Statement
What if we will be able to initialize immutable variables not only in the constructor?
How to do DI in a ideal Android world with Kotlin?
Problem Statement
public class SomeActivity: Activity {
val logic: BusinessLogic by inject()
public void callMe() {
//some code
logic.doSomeStuff();
//some other code
}
}
Problem Statement
public class SomeActivity: Activity {
val logic: BusinessLogic by inject()
public void callMe() {
//some code
logic.doSomeStuff();
//some other code
}
}
Kodein
Kodein
“Kodein is a very useful dependency retrieval container, it is very easy to use and
configure.”
Kodein
val kodein = Kodein {
bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) }
bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) }
bind<MyDataSource>("Mock") with singleton { MockDataSource() }
constant("samsung") with "(╯°□°)╯︵ ┻━┻"
}
Kodein
val kodein = Kodein {
bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) }
bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) }
bind<MyDataSource>("Mock") with singleton { MockDataSource() }
constant("samsung") with "(╯°□°)╯︵ ┻━┻"
}
Kodein
val kodein = Kodein {
bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) }
bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) }
bind<MyDataSource>("Mock") with singleton { MockDataSource() }
constant("samsung") with "(╯°□°)╯︵ ┻━┻"
}
Kodein
val kodein = Kodein {
bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) }
bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) }
bind<MyDataSource>("Mock") with singleton { MockDataSource() }
constant("samsung") with "(╯°□°)╯︵ ┻━┻"
}
Kodein
val kodein = Kodein {
bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) }
bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) }
bind<MyDataSource>("Mock") with singleton { MockDataSource() }
constant("samsung") with "(╯°□°)╯︵ ┻━┻"
}
Kodein: Retrieval
val diceFactory: (Int) -> Dice = kodein.factory()
val dataSource: MyDataSource = kodein.instance()
val randomProvider: () -> Random = kodein.provider()
val someConstant: String = kodein.instance("samsung")
Kodein: Retrieval
val diceFactory: (Int) -> Dice = kodein.factoryOrNull()
val dataSource: MyDataSource = kodein.instanceOrNull()
val randomProvider: () -> Random = kodein.providerOrNull()
val someConstant: String = kodein.instanceOrNull("samsung")
Kodein: Being Kodein aware
class MyManager(override val kodein: Kodein) : KodeinAware {
val datasource: DataSource = instance()
val random: Random = instance()
}
Kodein: Via lazy properties
class Controller(private val kodein: Kodein) {
private val dataSource: MyDataSource by kodein.lazy.instance()
private val randomProvider: () -> Random by kodein.lazy.provider()
private val someConstant: String by kodein.lazy.instance("samsung")
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
Kodein: Via an injector
class Controller() {
private val injector = KodeinInjector()
private val dataSource: MyDataSource by injector.instance()
private val randomProvider: () -> Random by injector.provider()
private val someConstant: String by injector.instance("samsung")
private val kodein by injector.kodein()
fun whenReady(kodein: Kodein) = injector.inject(kodein)
}
KodeinInjector.UninjectedException
Kodein: Android
“Kodein does work on Android as-is. The kodein-android extension adds
multiple android-specific utilities to Kodein.
Using or not using this extension really depends on your needs.”
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
● Scopes
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
● Scopes
● Auto Scopes
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
● Scopes
● Auto Scopes
● Modules
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
● Scopes
● Auto Scopes
● Modules
Kodein: Other stuff
● Deep integration with Android if needed (interfaces, base classes)
● Scopes
● Auto Scopes
● Modules
Kodein Summary
● Use Kotlin features
● Same as Dagger 2
● A LOT of stuff inside
Kodein Summary
Problem Statement
What if our project is not so big?
Koin
Koin
“A small library for writing dependency injection in a concise and pragmatic way.
No proxy, no code generation, no introspection. Just DSL and functional Kotlin
magic!”
Koin: DSL
applicationContext - create a Koin Module
factory - provide a factory bean definition
bean - provide a bean definition
bind - additional Kotlin type binding for given bean definition
Koin: Module
val myModule = applicationContext {
// your definitions here
}
Koin: Provide keyword
Parameters:
● name (optional, default value is “”) - name for that bean definition (used for
name resolution)
● isSingleton (optional, default value is true) - define if the bean definition
will be singleton or factory
● definition - a lambda function, describing how to build the component - This
function generally call the constructor of the class component
Koin: Provide keyword
val myModule = applicationContext {
provide { MyComponent() } //just call the constructor of MyComponent
provide("MyCmp") { MyComponent() } //will be resolved with "MyCmp" name
provide(isSingleton = false) { MyComponent() } //default true
}
Koin: Binding additional types
val myModule = applicationContext {
// Define bean with type MyDataSource and additional type DataSource
provide { MyDataSource() } bind DataSource::class
}
OR
val myModule = applicationContext {
// Define bean with type DataSource
provide { MyDataSource() as DataSource }
}
Koin: Dependency resolution
val myModule = applicationContext {
bean { SQLiteHelper() }
bean { UserRepository(get<SQLiteHelper>()) }
}
Koin: Dependency resolution
val myModule = applicationContext {
bean("default") { MyComponentA() }
bean("other") { MyComponentA() }
bean { MyComponentB(get("default")) }
}
Koin: The Very Start Function
class MyApplication : Application(){
override fun onCreate() {
super.onCreate()
// Start Koin
startKoin(this, listOf(myModule))
}
}
Koin: Properties
Koin will check if koin.properties is available, to load your properties. It has to be
in src/main/resources Kotlin folder or asset Android folder
OR/AND
startKoin(listOf(myModule),properties = HashMap(...properties))
Koin: Injecting
● Use a adapted Koin module, to help you inject into runtime components
(Activity, Fragments, Controller …)
● Tag a component as KoinComponent. In Android, the following classes have
already KoinComponent features: Application,Context, Activity,
Fragment, Service
Koin: Working with Contexts
A context is a logical subset of bean definitions inside a module:
val myModule = applicationContext {
context("myContext"){
bean { MyComponentA() }
bean { MyComponentB(get()) }
}
}
Koin: Working with Contexts
A context is a logical subset of bean definitions inside a module:
val myModule = applicationContext {
context("myContext"){
bean { MyComponentA() }
bean { MyComponentB(get()) }
}
}
Koin: Releasing Contexts
abstract class MyCustomActivity : AppCompatActivity() {
abstract val contextName: String
override fun onPause() {
releaseContext(contextName)
super.onPause()
}
}
Koin: Context isolation
val myModule = applicationContext {
context("Activity"){
context("Fragment"){
}
}
context("Service"){
}
}
Koin Android: DSL
Access all the Koin DSL, plus:
● androidApplication() - resolve Application type dependency
● viewModel - declare a ViewModel component (koin-android-architecture
only)
Koin Android: Injection
● get() get desired dependency
● by inject() lazy delagate to inject the desired dependency
● by property() lazy inject property value
● releaseContext() release the given context by its name
Koin Android: ViewModel
In Activity or Fragment:
● getViewModel() fetch given ViewModel dependency
● by viewModel() lazy delegate to inject the ViewModel
In Fragment:
● Fragment.getSharedViewModel() fetch given ViewModel dependency -
shared with Activity
● Fragment by sharedViewModel() lazy delegate to inject the ViewModel -
shared with Activity
Koin Android: ViewModel
class MyActivity : AppCompatActivity(){
override fun onCreate() {
super.onCreate()
val myModel = getViewModel<MyModel>()
}
}
OR
class MyActivity : AppCompatActivity(){
val myModel by viewModel<MyModel>()
}
Koin Android: ViewModel
class MyFragment : Fragment(){
val myModel by viewModel<MyModel>()
}
OR
class MyFragment : Fragment(){
// Create new instance
val myModel by viewModel<MyModel>(fromActivity = false)
}
Koin Summary
● Simple
● Stupid
● Manually controlled
● NOT RELEASED YET
Koin Summary
● Simple
● Stupid
● Manually controlled
● NOT RELEASED YET
General Summary
Dependency Injections in Kotlin

More Related Content

Dependency Injections in Kotlin

  • 2. Problem Statement How to do DI in a perfect world?
  • 3. Problem Statement public class SomeController { public final BusinessLogic logic; public SomeController(BusinessLogic logic) { this.logic = logic; } public void callMe() { //some stuff logic.doSomeStuff(); //some other stuff } }
  • 4. Problem Statement public class SomeController { public final BusinessLogic logic; public SomeController(BusinessLogic logic) { this.logic = logic; } public void callMe() { //some stuff logic.doSomeStuff(); //some other stuff } }
  • 5. Problem Statement How to do DI in perfect Java world?
  • 6. Problem Statement public class SomeController { public final BusinessLogic logic; @Inject public SomeController(BusinessLogic logic) { this.logic = logic; } public void callMe() { //some stuff logic.doSomeStuff(); //some other stuff } }
  • 7. Problem Statement public class SomeController { public final BusinessLogic logic; @Inject public SomeController(BusinessLogic logic) { this.logic = logic; } public void callMe() { //some stuff logic.doSomeStuff(); //some other stuff } }
  • 8. Problem Statement How to do DI in a real Android world? (until ActivityFactory)
  • 9. Problem Statement public class SomeActivity extends Activity { @Inject public BusinessLogic logic; @Override public void onCreate() { //some code Injector injector = getMyCoolInjector(this); injector.inject(this); //some code } }
  • 10. Problem Statement public class SomeActivity extends Activity { @Inject public BusinessLogic logic; @Override public void onCreate() { //some code Injector injector = getMyCoolInjector(this); injector.inject(this); //some code } }
  • 11. Problem Statement ● Not final anymore ● SomeActivity should know about Injector implementation ● Testing is hard (because of p.2) ● Looks ugly
  • 13. Field Injections @Inject lateinit var feedViewModel:FeedViewModel @Inject @field:DatabaseInfo @JvmField var dbVersion: Int = -1
  • 14. Field Injections @Inject lateinit var feedViewModel:FeedViewModel @Inject @field:DatabaseInfo @JvmField var dbVersion: Int = -1
  • 15. Field Injections @Inject lateinit var feedViewModel:FeedViewModel @Inject @field:DatabaseInfo @JvmField var dbVersion: Int = -1
  • 16. Field Injections @Inject lateinit var feedViewModel:FeedViewModel @Inject @field:DatabaseInfo @JvmField var dbVersion: Int = -1
  • 17. Dagger 2 Summary ● Good for migration from Java ● Everybody know it ● The fastest DI ever (probably) ● Oldschool
  • 18. Problem Statement What if we will be able to initialize immutable variables not only in the constructor?
  • 19. Problem Statement What if we will be able to initialize immutable variables not only in the constructor? How to do DI in a ideal Android world with Kotlin?
  • 20. Problem Statement public class SomeActivity: Activity { val logic: BusinessLogic by inject() public void callMe() { //some code logic.doSomeStuff(); //some other code } }
  • 21. Problem Statement public class SomeActivity: Activity { val logic: BusinessLogic by inject() public void callMe() { //some code logic.doSomeStuff(); //some other code } }
  • 23. Kodein “Kodein is a very useful dependency retrieval container, it is very easy to use and configure.”
  • 24. Kodein val kodein = Kodein { bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) } bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) } bind<MyDataSource>("Mock") with singleton { MockDataSource() } constant("samsung") with "(╯°□°)╯︵ ┻━┻" }
  • 25. Kodein val kodein = Kodein { bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) } bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) } bind<MyDataSource>("Mock") with singleton { MockDataSource() } constant("samsung") with "(╯°□°)╯︵ ┻━┻" }
  • 26. Kodein val kodein = Kodein { bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) } bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) } bind<MyDataSource>("Mock") with singleton { MockDataSource() } constant("samsung") with "(╯°□°)╯︵ ┻━┻" }
  • 27. Kodein val kodein = Kodein { bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) } bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) } bind<MyDataSource>("Mock") with singleton { MockDataSource() } constant("samsung") with "(╯°□°)╯︵ ┻━┻" }
  • 28. Kodein val kodein = Kodein { bind<MyDataSource>() with factory { url: MyDataSource -> MyDataSource(url) } bind<MyDataSource>("InMemory") with provider { MyDataSource(inMemory: true) } bind<MyDataSource>("Mock") with singleton { MockDataSource() } constant("samsung") with "(╯°□°)╯︵ ┻━┻" }
  • 29. Kodein: Retrieval val diceFactory: (Int) -> Dice = kodein.factory() val dataSource: MyDataSource = kodein.instance() val randomProvider: () -> Random = kodein.provider() val someConstant: String = kodein.instance("samsung")
  • 30. Kodein: Retrieval val diceFactory: (Int) -> Dice = kodein.factoryOrNull() val dataSource: MyDataSource = kodein.instanceOrNull() val randomProvider: () -> Random = kodein.providerOrNull() val someConstant: String = kodein.instanceOrNull("samsung")
  • 31. Kodein: Being Kodein aware class MyManager(override val kodein: Kodein) : KodeinAware { val datasource: DataSource = instance() val random: Random = instance() }
  • 32. Kodein: Via lazy properties class Controller(private val kodein: Kodein) { private val dataSource: MyDataSource by kodein.lazy.instance() private val randomProvider: () -> Random by kodein.lazy.provider() private val someConstant: String by kodein.lazy.instance("samsung") }
  • 33. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) }
  • 34. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) }
  • 35. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) }
  • 36. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) }
  • 37. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) }
  • 38. Kodein: Via an injector class Controller() { private val injector = KodeinInjector() private val dataSource: MyDataSource by injector.instance() private val randomProvider: () -> Random by injector.provider() private val someConstant: String by injector.instance("samsung") private val kodein by injector.kodein() fun whenReady(kodein: Kodein) = injector.inject(kodein) } KodeinInjector.UninjectedException
  • 39. Kodein: Android “Kodein does work on Android as-is. The kodein-android extension adds multiple android-specific utilities to Kodein. Using or not using this extension really depends on your needs.”
  • 40. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes)
  • 41. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes) ● Scopes
  • 42. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes) ● Scopes ● Auto Scopes
  • 43. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes) ● Scopes ● Auto Scopes ● Modules
  • 44. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes) ● Scopes ● Auto Scopes ● Modules
  • 45. Kodein: Other stuff ● Deep integration with Android if needed (interfaces, base classes) ● Scopes ● Auto Scopes ● Modules
  • 46. Kodein Summary ● Use Kotlin features ● Same as Dagger 2 ● A LOT of stuff inside
  • 48. Problem Statement What if our project is not so big?
  • 49. Koin
  • 50. Koin “A small library for writing dependency injection in a concise and pragmatic way. No proxy, no code generation, no introspection. Just DSL and functional Kotlin magic!”
  • 51. Koin: DSL applicationContext - create a Koin Module factory - provide a factory bean definition bean - provide a bean definition bind - additional Kotlin type binding for given bean definition
  • 52. Koin: Module val myModule = applicationContext { // your definitions here }
  • 53. Koin: Provide keyword Parameters: ● name (optional, default value is “”) - name for that bean definition (used for name resolution) ● isSingleton (optional, default value is true) - define if the bean definition will be singleton or factory ● definition - a lambda function, describing how to build the component - This function generally call the constructor of the class component
  • 54. Koin: Provide keyword val myModule = applicationContext { provide { MyComponent() } //just call the constructor of MyComponent provide("MyCmp") { MyComponent() } //will be resolved with "MyCmp" name provide(isSingleton = false) { MyComponent() } //default true }
  • 55. Koin: Binding additional types val myModule = applicationContext { // Define bean with type MyDataSource and additional type DataSource provide { MyDataSource() } bind DataSource::class } OR val myModule = applicationContext { // Define bean with type DataSource provide { MyDataSource() as DataSource } }
  • 56. Koin: Dependency resolution val myModule = applicationContext { bean { SQLiteHelper() } bean { UserRepository(get<SQLiteHelper>()) } }
  • 57. Koin: Dependency resolution val myModule = applicationContext { bean("default") { MyComponentA() } bean("other") { MyComponentA() } bean { MyComponentB(get("default")) } }
  • 58. Koin: The Very Start Function class MyApplication : Application(){ override fun onCreate() { super.onCreate() // Start Koin startKoin(this, listOf(myModule)) } }
  • 59. Koin: Properties Koin will check if koin.properties is available, to load your properties. It has to be in src/main/resources Kotlin folder or asset Android folder OR/AND startKoin(listOf(myModule),properties = HashMap(...properties))
  • 60. Koin: Injecting ● Use a adapted Koin module, to help you inject into runtime components (Activity, Fragments, Controller …) ● Tag a component as KoinComponent. In Android, the following classes have already KoinComponent features: Application,Context, Activity, Fragment, Service
  • 61. Koin: Working with Contexts A context is a logical subset of bean definitions inside a module: val myModule = applicationContext { context("myContext"){ bean { MyComponentA() } bean { MyComponentB(get()) } } }
  • 62. Koin: Working with Contexts A context is a logical subset of bean definitions inside a module: val myModule = applicationContext { context("myContext"){ bean { MyComponentA() } bean { MyComponentB(get()) } } }
  • 63. Koin: Releasing Contexts abstract class MyCustomActivity : AppCompatActivity() { abstract val contextName: String override fun onPause() { releaseContext(contextName) super.onPause() } }
  • 64. Koin: Context isolation val myModule = applicationContext { context("Activity"){ context("Fragment"){ } } context("Service"){ } }
  • 65. Koin Android: DSL Access all the Koin DSL, plus: ● androidApplication() - resolve Application type dependency ● viewModel - declare a ViewModel component (koin-android-architecture only)
  • 66. Koin Android: Injection ● get() get desired dependency ● by inject() lazy delagate to inject the desired dependency ● by property() lazy inject property value ● releaseContext() release the given context by its name
  • 67. Koin Android: ViewModel In Activity or Fragment: ● getViewModel() fetch given ViewModel dependency ● by viewModel() lazy delegate to inject the ViewModel In Fragment: ● Fragment.getSharedViewModel() fetch given ViewModel dependency - shared with Activity ● Fragment by sharedViewModel() lazy delegate to inject the ViewModel - shared with Activity
  • 68. Koin Android: ViewModel class MyActivity : AppCompatActivity(){ override fun onCreate() { super.onCreate() val myModel = getViewModel<MyModel>() } } OR class MyActivity : AppCompatActivity(){ val myModel by viewModel<MyModel>() }
  • 69. Koin Android: ViewModel class MyFragment : Fragment(){ val myModel by viewModel<MyModel>() } OR class MyFragment : Fragment(){ // Create new instance val myModel by viewModel<MyModel>(fromActivity = false) }
  • 70. Koin Summary ● Simple ● Stupid ● Manually controlled ● NOT RELEASED YET
  • 71. Koin Summary ● Simple ● Stupid ● Manually controlled ● NOT RELEASED YET