Successfully reported this slideshow.
Your SlideShare is downloading. ×

Koin Quickstart

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Kotlin - Better Java
Kotlin - Better Java
Loading in …3
×

Check these out next

1 of 65 Ad

Koin Quickstart

Download to read offline

Slides from a talk and live-coding session about Koin, a pragmatic and lightweight Dependency Injection framework for Kotlin. This talk was given at Auckland Android Community on Dec 5.
https://www.meetup.com/Android-Meetup/events/256734688/

Slides from a talk and live-coding session about Koin, a pragmatic and lightweight Dependency Injection framework for Kotlin. This talk was given at Auckland Android Community on Dec 5.
https://www.meetup.com/Android-Meetup/events/256734688/

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to Koin Quickstart (20)

Advertisement

Recently uploaded (20)

Koin Quickstart

  1. 1. Koin Quickstart Matt Clarke - Auckland Android Community - Dec 2018
  2. 2. What is Koin?
  3. 3. What is Koin? • From insert-koin.io:
  4. 4. What is Koin? • From insert-koin.io: • A pragmatic lightweight dependency injection framework for Kotlin developers.
  5. 5. What is Koin? • From insert-koin.io: • A pragmatic lightweight dependency injection framework for Kotlin developers. • Written in pure Kotlin, using functional resolution only: no proxy, no code generation, no reflection.
  6. 6. What is Koin? • From insert-koin.io: • A pragmatic lightweight dependency injection framework for Kotlin developers. • Written in pure Kotlin, using functional resolution only: no proxy, no code generation, no reflection. • Koin is a DSL, a light container and a pragmatic API
  7. 7. What is Koin?
  8. 8. What is Koin? public class Person { private String name; private int age = 0; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (name != null ? !name.equals(person.name) : person.name != null) return false; if (age != 0 ? age != person.age : person.age != 0) return false; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return "Person{" + "name='" + name + ''' + ", age='" + age + ''' + '}'; } }
  9. 9. What is Koin? data class Person(var name: String, var age: Int)
  10. 10. What is Koin? data class Person(var name: String, var age: Int) i.e. “Koin is to Dagger as Kotlin is to Java”
  11. 11. Live (mob) coding
  12. 12. Deep(er) dive: How does any of this work?
  13. 13. Deep(er) dive: How does any of this work? val postModule = module { single { PostPresenter(get()) } }
  14. 14. Deep(er) dive: How does any of this work? val postModule = module { single { PostPresenter(get()) } }
  15. 15. How does any of this work?
  16. 16. How does any of this work? /** * Create a Module * Gather definitions * @param path : Path of the module * @param createOnStart : module definitions will be tagged as `createOnStart` * @param override : allow all definitions from module to override definitions */ fun module( path: String = Path.ROOT, createOnStart: Boolean = false, override: Boolean = false, definition: ModuleDefinition.() -> Unit ): Module = { koinContext -> ModuleDefinition(path, createOnStart, override, koinContext).apply(definition) } org/koin/dsl/module/Module.kt
  17. 17. How does any of this work? /** * Create a Module * Gather definitions * @param path : Path of the module * @param createOnStart : module definitions will be tagged as `createOnStart` * @param override : allow all definitions from module to override definitions */ fun module( path: String = Path.ROOT, createOnStart: Boolean = false, override: Boolean = false, definition: ModuleDefinition.() -> Unit ): Module = { koinContext -> ModuleDefinition(path, createOnStart, override, koinContext).apply(definition) } org/koin/dsl/module/Module.kt
  18. 18. How does any of this work? /** * Create a Module * Gather definitions * @param path : Path of the module * @param createOnStart : module definitions will be tagged as `createOnStart` * @param override : allow all definitions from module to override definitions */ fun module( path: String = Path.ROOT, createOnStart: Boolean = false, override: Boolean = false, definition: ModuleDefinition.() -> Unit ): Module = { koinContext -> ModuleDefinition(path, createOnStart, override, koinContext).apply(definition) } org/koin/dsl/module/Module.kt
  19. 19. How does any of this work?
  20. 20. How does any of this work? kotlinlang.org/docs/reference/lambdas.html
  21. 21. How does any of this work?
  22. 22. How does any of this work? val postModule = module { single { PostPresenter(get()) } }
  23. 23. How does any of this work? val postModule: Module = module(definition = { single { PostPresenter(get()) } })
  24. 24. How does any of this work? val postModule: Module = module(definition = { single { PostPresenter(get()) } })
  25. 25. How does any of this work?
  26. 26. How does any of this work? /** * Create a Module * Gather definitions * @param path : Path of the module * @param createOnStart : module definitions will be tagged as `createOnStart` * @param override : allow all definitions from module to override definitions */ fun module( path: String = Path.ROOT, createOnStart: Boolean = false, override: Boolean = false, definition: ModuleDefinition.() -> Unit ): Module = { koinContext -> ModuleDefinition(path, createOnStart, override, koinContext).apply(definition) } org/koin/dsl/module/Module.kt
  27. 27. How does any of this work? /** * Create a Module * Gather definitions * @param path : Path of the module * @param createOnStart : module definitions will be tagged as `createOnStart` * @param override : allow all definitions from module to override definitions */ fun module( path: String = Path.ROOT, createOnStart: Boolean = false, override: Boolean = false, definition: ModuleDefinition.() -> Unit ): Module = { koinContext -> ModuleDefinition(path, createOnStart, override, koinContext).apply(definition) } org/koin/dsl/module/Module.kt
  28. 28. How does any of this work? val postModule: Module = module(definition = { single { PostPresenter(get()) } })
  29. 29. How does any of this work? val postModule: Module = module(definition = { this.single { PostPresenter(get()) } })
  30. 30. How does any of this work? val postModule: Module = module(definition = { this.single { PostPresenter(get()) } })
  31. 31. How does any of this work?
  32. 32. How does any of this work? /** * Provide a single instance definition * (unique instance) * * @param name * @param createOnStart - need to be created at start * @param override - allow definition override * @param definition */ inline fun <reified T : Any> single( name: String = "", createOnStart: Boolean = false, override: Boolean = false, noinline definition: Definition<T> ): BeanDefinition<T> { return provide(name, createOnStart, override, Kind.Single, definition) } org/koin/dsl/context/ModuleDefinition.kt
  33. 33. Type-Safe Builders
  34. 34. Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html
  35. 35. Type-Safe Builders
  36. 36. Type-Safe Builders
  37. 37. What about this?
  38. 38. What about this? /** * Activity displaying the list of posts */ class PostActivity : AppCompatActivity(), PostView { private val presenter: PostPresenter by inject() // ...
  39. 39. What about this? /** * Activity displaying the list of posts */ class PostActivity : AppCompatActivity(), PostView { private val presenter: PostPresenter by inject() // ...
  40. 40. No magic
  41. 41. No magic • Koin takes full advantage of Kotlin’s adv. language features
  42. 42. No magic • Koin takes full advantage of Kotlin’s adv. language features • E.g. reified generics, lambdas with receivers, type inference
  43. 43. No magic • Koin takes full advantage of Kotlin’s adv. language features • E.g. reified generics, lambdas with receivers, type inference • Less opaque/magical than annotation processing pipeline for application developers
  44. 44. Testability?
  45. 45. Testability? // Just tag your class with KoinTest to unlock your testing power class SimpleTest : KoinTest { // lazy inject BusinessService into property val service : BusinessService by inject() @Test fun myTest() { // You can start your Koin configuration startKoin(myModules) // or directly get any instance val service : BusinessService = get() // Don't forget to close it at the end closeKoin() } }
  46. 46. What about Scopes?
  47. 47. What about Scopes? val appModule = module { // single instance of HelloRepository single<HelloRepository> { HelloRepositoryImpl() } // Scoped MyScopePresenter instance scope("session") { MyScopePresenter(get())} }
  48. 48. What about Scopes?
  49. 49. What about Scopes? class MyScopeActivity : AppCompatActivity() { // inject MyScopePresenter from "session" scope val scopePresenter: MyScopePresenter by inject() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_simple) // bind "session" scope to component lifecycle bindScope(getOrCreateScope("session")) //... } }
  50. 50. Koin vs. Dagger overview
  51. 51. Koin vs. Dagger overview • Koin pros:
  52. 52. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn
  53. 53. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features
  54. 54. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration
  55. 55. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration • Nice, simple documentation
  56. 56. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration • Nice, simple documentation • Build speed (?)
  57. 57. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration • Nice, simple documentation • Build speed (?) • Koin cons:
  58. 58. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration • Nice, simple documentation • Build speed (?) • Koin cons: • Runtime dependency resolution (though minimal overhead)
  59. 59. Koin vs. Dagger overview • Koin pros: • Less boilerplate. Less arcane, easy to learn • No annotation processing/code gen. Just language features • Straightforward Android integration • Nice, simple documentation • Build speed (?) • Koin cons: • Runtime dependency resolution (though minimal overhead) • Newer, relatively unproven (compared to Dagger)
  60. 60. Is it Production-Ready?
  61. 61. Is it Production-Ready? • Research didn’t turn up much, but…
  62. 62. Is it Production-Ready? • Research didn’t turn up much, but… • Reached v1.0 in Sep (FWIW)
  63. 63. Is it Production-Ready? • Research didn’t turn up much, but… • Reached v1.0 in Sep (FWIW) • The author uses it in several production apps…
  64. 64. Is it Production-Ready? • Research didn’t turn up much, but… • Reached v1.0 in Sep (FWIW) • The author uses it in several production apps… • Workable team uses it prod, details here: https:// medium.com/@charbgr/bye-bye-dagger-1494118dcd41
  65. 65. Thanks!
 Questions/thoughts/ comments? Twitter: @kiwiandroiddev Email: kiwiandroiddev@gmail.com

×