Dependency Injection
 in Kotlin

Dependency Injection
 in Kotlin

# About me
- Twitter
- https://twitter.com/shihochandesu

- Github
- https://github.com/shihochan

# Links
- Example App
https://github.com/shihochan/KotlinDIExample

- Dagger2
https://google.github.io/dagger/

- Kodein
https://github.com/SalomonBrys/Kodein

- Kodein 4 full documentation
https://salomonbrys.github.io/Kodein/

# References
- AndroidDaggerSample
https://github.com/YukiMatsumura/AndroidDaggerSample

- Kotlin + Architecture Component + Dagger2によるAndroidアプリ設計
http://qiita.com/satorufujiwara/items/0f95ccfc3820d3ee1370

- Dagger 2 から Kotlin製DIコンテナ Kodein へ乗り換える
http://qiita.com/chibatching/items/04ca96cd454fe11ce5ad

- 【Android】Kotlin/KodeinではじめてのDI
http://shimbaroid.hatenablog.jp/entry/2017/06/11/011103

0ef9d512061aa068aafd47c3e3f13ce0?s=128

Yuki Shiho

July 19, 2017
Tweet

Transcript

  1. :VLJ4IJIP !TIJIPDIBO %FQFOEFODZ*OKFDUJPO
 JO,PUMJO DBLUJO

  2. "CPVUNF 䘊歂⣇秀:6,*4)*)0 !TIJIPDIBO "OESPJE"QQ%FWFMPQFSBU$ZCFS"HFOU *OD !TIJIPDIBOEFTV 4IJCVZBBQL

  3. 4BNQMF$PEFT IUUQTHJUIVCDPNTIJIPDIBO ,PUMJO%*&YBNQMF

  4. ˖ %*XJUI%BHHFS ˖ %*XJUI,PEFJO ˖ $PODMVTJPO "HFOEB

  5. %FQFOEFODZ*OKFDUJPO

  6. $BTFXJUI%BHHFS

  7. %*XJUI%BHHFS compile "com.google.dagger:dagger:2.11" compile "com.google.dagger:dagger-android:2.11" compile "com.google.dagger:dagger-android-support:2.11" kapt "com.google.dagger:dagger-compiler:2.11" kapt

    "com.google.dagger:dagger-android-processor:2.11" build.gradle ˖ VTF%BHHFSW ˖ Wד鷄⸇ׁ׸׋䭁䓸ٌآُ٦ٕ׾ⵃ欽
  8. .PEVMFJO%BHHFS @Module class AppModule(private val app: Application) { @Provides @PerApp

    fun providesApp() = app } AppModule.kt ˖ !.PEVMF׾➰♷ ˖ *OKFDUׅ׷ًاحسח!1SPWJEFT׾➰♷
  9. .PEVMFJO%BHHFS @Module abstract class ActivityBinderModule { @PerActivity @ContributesAndroidInjector abstract fun

    contributeTopActivityInjector(): TopActivity } ActivityBinderModule.kt ˖ "DUJWJUZפך*OKFDU ˖ !$POUSJCVUFT"OESPJE*OKFDUPS׾ⵃ欽
  10. .PEVMFJO%BHHFS public final class DaggerAppComponent implements AppComponent { private Provider<~~~.TopActivitySubcomponent.Builder>

    topActivitySubcomponentBuilderProvider; private void initialize(final Builder builder) { this.topActivitySubcomponentBuilderProvider = new dagger.internal.Factory< ~~~.TopActivitySubcomponent.Builder>() { @Override public ~~~.TopActivitySubcomponent.Builder get() { return new TopActivitySubcomponentBuilder(); } }; //… } DaggerAppComponent.kt
  11. $PNQPOFOUJO%BHHFS @Component( modules = arrayOf( AppModule::class, ActivityBinderModule::class, AndroidSupportInjectionModule::class) ) @PerApp

    interface AppComponent : AndroidInjector<MainApp> { //… } AppComponent.kt ˖ !$PNQPOFOU׾➰♷
  12. $PNQPOFOUJO%BHHFS //… @PerApp interface AppComponent : AndroidInjector<MainApp> { @Component.Builder abstract

    class Builder :ɹ
 ɹɹɹɹɹɹɹAndroidInjector.Builder<MainApp>() { abstract fun appModule(module: AppModule): Builder } } AppComponent.kt ˖ !$PNQPOFOU#VJMEFS׾㹋鄲
  13. "QQMJDBUJPOJO%BHHFS ˖ %BHHFS"QQMJDBUJPO׾竰䪫 ˖ ؝،؝ٝه٦طٝزך*OKFDUPSָ㹋鄲 ˖ )BT"DUJWJUZ*OKFDUPS ˖ )BT'SBHNFOU*OKFDUPS ˖

    )BT4FSWJDF*OKFDUPS ˖ )BT#SPBEDBTU3FDFJWFS*OKFDUPS ˖ )BT$POUFOU1SPWJEFS*OKFDUPS ˖ ؙٓأせָずせזךד岣䠐 ˖ EBHHFSBOESPJE%BHHFS"QQMJDBUJPO ˖ EBHHFSBOESPJETVQQPSU%BHHFS"QQMJDBUJPO
  14. "QQMJDBUJPOJO%BHHFS class MainApp : DaggerApplication() { //… override fun applicationInjector()

    : AndroidInjector<out DaggerApplication> { return DaggerAppComponent.builder() .appModule(AppModule(app)) .create(app) } } MainApp.kt ˖ BQQMJDBUJPO*OKFDUPS ׾0WFSSJEF
  15. "DUJWJUZJO%BHHFS class TopActivity : DaggerAppCompatActivity() { @Inject lateinit var app:

    Application override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } //… } TopActivity.kt ˖ %BHHFS"QQ$PNQBU"DUJWJUZ׾竰䪫 ˖ "OESPJE*OKFDUJPOJOKFDU UIJT
  16. يؤְ

  17. $BTFXJUI,PEFJO

  18. %*XJUI,PEFJO ˖ ,PUMJO%FQFOEFODZ*OKFDUJPO ˖ GFBUVSF ˖ -B[JMZJOTUBOUJBUFZPVSEFQFOEFODJFTXIFOOFFEFE ˖ 4UPQDBSJOHBCPVUEFQFOEFODZJOJUJBMJ[BUJPOPSEFS ˖

    &BTJMZCJOEDMBTTFTPSJOUFSGBDFTUPUIFJSJOTUBODFPS QSPWJEFS ˖ &BTJMZEFCVHZPVSEFQFOEFODZCJOEJOHTBOE SFDVSTJPOT
  19. %*XJUI,PEFJO ˖ ,PEFJOJTBHPPEDIPJDFCFDBVTF ˖ *UJTTNBMM GBTUBOEPQUJNJ[FE
  NBLFTFYUFOTJWFVTFPGJOMJOF  ˖

    *UQSPQPTFTBWFSZTJNQMFBOESFBEBCMFEFDMBSBUJWF %4- ˖ *UJTOPUTVCKFDUUPUZQFFSBTVSF BT+BWBJT  ˖ *UJOUFHSBUFTOJDFMZXJUI"OESPJE ˖ *UQSPQPTFTBWFSZLPUMJOFTRVFJEJPNBUJD"1* ˖ *UDBOCFVTFEJOQMBJO+BWB
  20. ,PUMJO5FDIOJRVF JO,PEFJO

  21. SFJFE // not use reified fun getName(clazz: Class<*>): String =

    clazz.simpleName
 
 val name = getName(Activity::class.java) // use reified inline fun <reified T> getNameWithReified(): String = T::class.java.simpleName val name = getNameWithReified<Activity>()
  22. JOMJOF inline fun inlineFun(fun: () -> Unit) { fun() fun()

    fun() }
 inlineFun { print("hoge") }
  23. JOY public infix fun <A, B> A.to(that: B): Pair<A, B>

    = Pair(this, that) val pair1 = 1 to 2 // Pair(1, 2) val pair2 = 1.to(2)
  24. %*XJUI,PEFJO compile "com.github.salomonbrys.kodein:kodein:4.0.0" compile "com.github.salomonbrys.kodein:kodein-android:4.0.0" build.gradle

  25. .PEVMFJO,PEFJO fun appModule(app: Application) = Kodein.Module { bind<Application>() with instance(app)

    } AppModule.kt ˖ !.PEVMF,PEFJO.PEVMF ˖ !1SPWJEFCJOESFJFE5LPUMJO"OZ JOpY SFJpFE CJOE$MBTT QSPWJEF*OTUBODF
  26. "QQMJDBUJPOJO,PEFJO class KodeinApp : Application(), KodeinAware { override val kodein:

    Kodein by Kodein.lazy { import(appModule(this@KodeinApp)) } } KodeinApp.kt ˖ ,PEFJO"XBSF׾㹋鄲
  27. "DUJWJUZJO,PEFJO class TopActivity : KodeinAppCompatActivity() { private val app: Application

    by instance() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } //… } TopActivity.kt ˖ ,PEFJO"QQ$PNQBU"DUJWJUZ׾竰䪫
  28. 㼰׃ⴓַ׶װְׅ

  29. 5BHHFECJOEJOHT val kodein = Kodein { bind<Dice>() with factory {

    sides: Int -> RandomDice(sides) } bind<Dice>("DnD10") with provider { RandomDice(10) } bind<Dice>("DnD20") with singleton { RandomDice(20) } }
  30. 4DPQFETJOHMFUPOT val kodein = Kodein { bind<Logger>() with scopedSingleton(contextScope) {

    LogManager.getNamedLogger(it.localClassName) } } val logger: Logger = kodein.with(context).instance() // Same object as logger val sameLogger: Logger = kodein.with(context).instance() // different object than logger val otherLogger: Logger = kodein.with(otherContext).instance()
  31. $PODMVTJPO

  32. $PODMVTJPO ˖ %BHHFS ˖  ˖ ؝ٝػ؎ָٕ鸐׸ל⹛ֻ ˖ ِ٦ؠ٦ָ㢳ְ⹛⡲׾ֹ׍׿ה椚鍑דֹ׸ל㸜㹀 ׃ג⥂㸚〳腉

    ˖  ˖ ؝٦س欰䧭ח״׶ًاحس侧ָ㟓ִ׷ ˖ 欰䧭ׁ׸׋؝٦سך〳铣䚍ָ䝤ְ ˖ ,BQU
  33. $PODMVTJPO ˖ ,PEFJO ˖  ˖ JOKFDUׁ׸׋⣛㶷䚍׾WBMחדֹ׷ ˖ ؝٦س欰䧭ָזְךדًاحس侧ָ㟓ִזְ ˖

    〳铣䚍ָ넝ְ ˖  ˖ 㹋遤儗ؒٓ٦ָ饯ֿ׷ ˖ ِ٦ؠ٦ָ㼰זְ頾⫈חז׷〳腉䚍
  34. $PODMVTJPO LBQUא׵ְ

  35. :VLJ4IJIP !TIJIPDIBO 5IBOLZPV DBLUJO