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. 8.

    .PEVMFJO%BHHFS @Module class AppModule(private val app: Application) { @Provides @PerApp

    fun providesApp() = app } AppModule.kt ˖ !.PEVMF׾➰♷ ˖ *OKFDUׅ׷ًاحسח!1SPWJEFT׾➰♷
  2. 9.

    .PEVMFJO%BHHFS @Module abstract class ActivityBinderModule { @PerActivity @ContributesAndroidInjector abstract fun

    contributeTopActivityInjector(): TopActivity } ActivityBinderModule.kt ˖ "DUJWJUZפך*OKFDU ˖ !$POUSJCVUFT"OESPJE*OKFDUPS׾ⵃ欽
  3. 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
  4. 11.

    $PNQPOFOUJO%BHHFS @Component( modules = arrayOf( AppModule::class, ActivityBinderModule::class, AndroidSupportInjectionModule::class) ) @PerApp

    interface AppComponent : AndroidInjector<MainApp> { //… } AppComponent.kt ˖ !$PNQPOFOU׾➰♷
  5. 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׾㹋鄲
  6. 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
  7. 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
  8. 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
  9. 16.
  10. 18.

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

    &BTJMZCJOEDMBTTFTPSJOUFSGBDFTUPUIFJSJOTUBODFPS QSPWJEFS ˖ &BTJMZEFCVHZPVSEFQFOEFODZCJOEJOHTBOE SFDVSTJPOT
  11. 19.

    %*XJUI,PEFJO ˖ ,PEFJOJTBHPPEDIPJDFCFDBVTF ˖ *UJTTNBMM GBTUBOEPQUJNJ[FE
  NBLFTFYUFOTJWFVTFPGJOMJOF  ˖

    *UQSPQPTFTBWFSZTJNQMFBOESFBEBCMFEFDMBSBUJWF %4- ˖ *UJTOPUTVCKFDUUPUZQFFSBTVSF BT+BWBJT  ˖ *UJOUFHSBUFTOJDFMZXJUI"OESPJE ˖ *UQSPQPTFTBWFSZLPUMJOFTRVFJEJPNBUJD"1* ˖ *UDBOCFVTFEJOQMBJO+BWB
  12. 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>()
  13. 22.

    JOMJOF inline fun inlineFun(fun: () -> Unit) { fun() fun()

    fun() }
 inlineFun { print("hoge") }
  14. 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)
  15. 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
  16. 26.

    "QQMJDBUJPOJO,PEFJO class KodeinApp : Application(), KodeinAware { override val kodein:

    Kodein by Kodein.lazy { import(appModule(this@KodeinApp)) } } KodeinApp.kt ˖ ,PEFJO"XBSF׾㹋鄲
  17. 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׾竰䪫
  18. 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) } }
  19. 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()
  20. 32.

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

    ˖  ˖ ؝٦س欰䧭ח״׶ًاحس侧ָ㟓ִ׷ ˖ 欰䧭ׁ׸׋؝٦سך〳铣䚍ָ䝤ְ ˖ ,BQU
  21. 33.

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

    〳铣䚍ָ넝ְ ˖  ˖ 㹋遤儗ؒٓ٦ָ饯ֿ׷ ˖ ِ٦ؠ٦ָ㼰זְ頾⫈חז׷〳腉䚍