タップルでたっぷりDaggerを使って マルチモジュール構築している話 :)

2793f1fe246c9299c2416062d22bfb99?s=47 Sato Shun
September 10, 2019

タップルでたっぷりDaggerを使って マルチモジュール構築している話 :)

タップルでたっぷりDaggerを使ってマルチモジュール構築している話です!

2793f1fe246c9299c2416062d22bfb99?s=128

Sato Shun

September 10, 2019
Tweet

Transcript

  1. CA.apk #8 ࠤ౻ ൏ / Sato Shun Twitter: @stsn_jp GitHub:

    satoshun λοϓϧͰͨͬ΀ΓDaggerΛ࢖ͬͯ ϚϧνϞδϡʔϧߏங͍ͯ͠Δ࿩ :)
  2. ँࣙ • λΠτϧ͸ɺogaclejapan͞ΜͷɺFlux de Relax :) Λࢀ ߟʹ͓ͯ͠Γ·͢ • https://speakerdeck.com/ogaclejapan/flux-de-relax

  3. ࠓճ࿩͞ͳ͍͜ͱ • Daggerૉ੖Β͍͠Μͩͧʂ͍ͬͯ͏࿩Ͱ͸ͳ͍Ͱ͢ • Koinͱ͔ଞͷϥΠϒϥϦͳͲͷൺֱͰ͸͋Γ·ͤΜ

  4. ࠓճ࿩͢͜ͱ • Daggerͷجຊߏ੒ • ϚϧνϞδϡʔϧͷجຊߏ੒ • AnalyticsϞδϡʔϧΛྫʹɺϥΠϒϥϦͷ஌ࣝΛϞ δϡʔϧʹด͡ࠐΊΔํ๏ • ֤FeatureϞδϡʔϧͷ࿩

    • RouterϞδϡʔϧͷ࿩
  5. Daggerͷجຊߏ੒ • Android Dagger࢖ͬͯ·͢ • ͨͩɺແཧͯ͠࢖͏ඞཁͳ͍ͱࢥ͏:D • Dynamic Feature Moduleͱ૬ੑѱ͍ʢଟ෼ʣ

    • ViewModelͷαϙʔτ͕ೖͬͨΒϫϯͪΌΜ (ISSUE͸͋Δ) • શ෦ɺDagger͔ΒΠϯελϯε࡞Ζ͏ͥʙͬͯײ͡Ͱ͸ͳ ͍ • ࣮͸DaggerΛͨͬ΀Γ࢖ͬͯͳ͍Ͱ͢
  6. None
  7. None
  8. None
  9. None
  10. None
  11. @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )

    interface AppComponent : AndroidInjector<App> { ... }
  12. @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )

    interface AppComponent : AndroidInjector<App> { ... }
  13. AnalyticsModule? • AnalyticsϞδϡʔϧʹఆٛ͞Ε͍ͯΔDaggerͷModule • Google Analytics for Firebaseʹґଘ͍ͯ͠Δ • Google

    Analytics͸ͱͬͬͬͯ΋Ͱ͔͍ϥΠϒϥϦ • Google AnalyticsͷҰ෦ͷػೳ͔͠࢖͍ͬͯͳ͍͠ɺ্ख͍͜ ͱ΍Γ͍ͨ
  14. interface Analytics { ... } .

  15. interface Analytics { ... } . @Singleton internal class FirebaseAnalyticsImpl

    @Inject constructor( private val app: Application ) : Analytics { ... } .
  16. interface Analytics { ... } . @Singleton internal class FirebaseAnalyticsImpl

    @Inject constructor( private val app: Application ) : Analytics { ... } .
  17. interface Analytics { . ... } . @Singleton internal class

    FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... } .
  18. interface Analytics { . ... . } . @Singleton internal

    class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module internal interface AnalyticsBindModule { . @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .
  19. interface Analytics { . ... . } . @Singleton internal

    class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module internal interface AnalyticsBindModule { . @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .
  20. interface Analytics { . ... . } . @Singleton .

    internal class FirebaseAnalyticsImpl @Inject constructor( . private val app: Application ) : Analytics { . ... . } . @Module . internal interface AnalyticsBindModule { .. @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } ..
  21. @Singleton internal class FirebaseAnalyticsImpl @Inject constructor( . private val app:

    Application ) : Analytics { ... . } . @Module . internal interface AnalyticsBindModule { .. @Binds fun bind(impl: FirebaseAnalyticsImpl): Analytics } .. . @Module(includes = [AnalyticsBindModule::class]) .. object AnalyticsModule { .. ... } .
  22. @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] )

    interface AppComponent : AndroidInjector<App> { ... }
  23. internal class GachaFragment : Fragment() { @Inject lateinit var analytics:

    FirebaseAnalyticsImpl ... } .
  24. internal class GachaFragment : Fragment() { @Inject lateinit var analytics:

    Analytics ... } .
  25. AnalyticsModule·ͱΊ • αʔυύʔςΟϥΠϒϥϦ͕ڊେ͔ͭɺͦͷ஌ࣝΛग़དྷ ΔݶΓด͡ࠐΊ͍ͨͱ͖ʹ༗ޮͳख๏ • ઐ༻ͷϞδϡʔϧΛ࡞ͬͯ͋͛ͯɺΠϯλϑΣʔεΛఆ ٛɻͦͯ͠ɺ࣮૷Λinternalɺ@BindsͰґଘΛఆٛ͢Δ • ·ͨϝϯς͞Ε͍ͯͳ͍ɺAPI͕ෳࡶͳࣾ಺ϥΠϒϥϦ ʹ΋༗ޮʹ࢖͏͜ͱ͕ग़དྷΔ

    • ϝϯς͞Εͯͳ͍ࣾ಺ϥΠϒϥϦͳΜͯͳ͍ΜͩΑͳ͊
  26. ֤FeatureϞδϡʔϧʹ͍ͭͯ • ֤FeatureϞδϡʔϧ͝ͱʹઐ༻ͷDaggerͷModuleΛ ͍࣋ͬͯΔ • gachaϞδϡʔϧ: GachaFeatureModule • settingϞδϡʔϧ: SettingFeatureModule

    • …
  27. @Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity }

  28. @Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(

    includes = [ GachaFeatureModule::class, ] ) interface FeatureModule
  29. @Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(

    includes = [ GachaFeatureModule::class, SettingFeatureModule::class, ] ) interface FeatureModule
  30. @Module interface GachaFeatureModule { @ContributesAndroidInjector fun contributeGachaActivity(): GachaActivity } @Module(

    includes = [ GachaFeatureModule::class, SettingFeatureModule::class, ShopFeatureModule::class, . ] ) interface FeatureModule
  31. GachaFeatureModule::class, . SettingFeatureModule::class, . ShopFeatureModule::class, . ] . ) .

    interface FeatureModule . @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] ) interface AppComponent : AndroidInjector<App> { ... }
  32. GachaFeatureModule::class, . SettingFeatureModule::class, . ShopFeatureModule::class, . ] . ) .

    interface FeatureModule . @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class ] ) interface AppComponent : AndroidInjector<App> { ... }
  33. FeatureϞδϡʔϧ·ͱΊ • FeatureϞδϡʔϧຖʹɺSettingFeatureModuleΈ͍ͨ ͳײ͡ͰModuleΛఆٛ͢Δ • ଞͷΫϥε͸internalͰఆٛ͢Δ͜ͱͰɺ֎ͷϞδϡʔϧ͔ ΒͷࢀরΛ࠷খݶʹ͢Δ͜ͱ͕ग़དྷΔ • ϞδϡʔϧؒͷґଘΛݮΒ͢͜ͱ͕ग़དྷΔʂ

  34. FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ • ֤ը໘ʢFeatureʣΛαϒϞδϡʔϧʹ੾Γग़ͨ͜͠ͱ Ͱɺ͓ޓ͍͕௚઀ࢀরग़དྷͳ͘ͳΔ • େ͖͘3ͭͷํ๏͕͋Δʢଟ෼ʣ

  35. FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 1 • จࣈྻʢϦϑϨΫγϣϯʣͰࢦఆ͢Δํ๏ • PlaidͰ࢖ΘΕͯΔํ๏

  36. object Activities { /** * AboutActivity */ object About :

    AddressableActivity { override val className = "$PACKAGE_NAME.about.ui.AboutA ctivity" } }
  37. FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 2 • ֤FeatureϞδϡʔϧ಺ʹભҠ༻ͷΠϯλʔϑΣʔεΛ ఆٛͯ͠ɺappϞδϡʔϧͰ࣮૷͢Δ • Navigation Componentͱͷ૬ੑ΋ྑ͍ʂʂ

  38. FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 2 • ֤FeatureϞδϡʔϧ಺ʹભҠ༻ͷΠϯλʔϑΣʔεΛ ఆٛͯ͠ɺappϞδϡʔϧͰ࣮૷͢Δ • Navigation Componentͱͷ૬ੑ΋ྑ͍ʂʂ

  39. FeatureϞδϡʔϧؒͷભҠʹ͍ͭͯ 3 • ઐ༻ͷϞδϡʔϧΛ࡞੒ͯ͠ɺ֤ը໘༻ͷΠϯλʔ ϑΣʔεΛఆٛ͢Δ • λοϓϧͰ͸ͦͷઐ༻ϞδϡʔϧΛRouterͰ࡞੒͍ͯ͠Δ • interface GachaDirections

    • interface SettingDirections • ֤FeatureϞδϡʔϧͰɺ͜ͷDirectionsΠϯλʔϑΣʔ εΛ࢖͍ભҠ͢Δ
  40. // ͜Ε͸RouterϞδϡʔϧͰఆٛ interface GachaDirections { .. @CheckResult fun createIntent(context: Context):

    Intent } .
  41. // ͜Ε͸RouterϞδϡʔϧͰఆٛ interface GachaDirections { .. @CheckResult fun createIntent(context: Context):

    Intent } . // ҎԼɺGachaϞδϡʔϧ internal class GachaDirectionsImpl @Inject constructor() : GachaDirections { . override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) } . } .
  42. } . // ҎԼɺGachaϞδϡʔϧ internal class GachaDirectionsImpl @Inject constructor() :

    GachaDirections { . override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) } . } . @Module internal interface GachaBindsModule { . @Binds fun bindGachaDirections(directions: GachaDirectionsImpl): GachaDirections } .
  43. override fun createIntent(context: Context): Intent { . return GachaActivity.createIntent(context) }

    . } . @Module internal interface GachaBindsModule { . @Binds fun bindGachaDirections(directions: GachaDirectionsImpl): GachaDirections } . @Module( includes = [ GachaBindsModule::class ] ) interface GachaFeatureModule
  44. @Singleton @Component( modules = [ AndroidInjectionModule::class, FeatureModule::class, AnalyticsModule::class, ] )

    interface AppComponent : AndroidInjector<App> { ... }
  45. @Module( includes = [ GachaFeatureModule::class, ... ] ) interface FeatureModule

  46. class MainActivity : AppCompatActivity() { @Inject lateinit var gachaDirections: GachaDirections

    }
  47. None
  48. ·ͱΊ • Google AnalyticsͳͲͷϥΠϒϥϦͷ஌ࣝΛด͡ࠐΊΔͨΊ ʹɺϞδϡʔϧΛఆٛ͠ɺDaggerͰґଘΛղܾ͢Δ • ϥΠϒϥϦ͕มΘΔՄೳੑ͕ߴ͍৔߹ɺΑΓ༗ޮ • ֤ը໘΁ͷભҠ͸ɺΠϯλʔϑΣʔεΛద੾ͳϞδϡʔϧʹ഑ ஔͯ͠ɺద੾ͳϞδϡʔϧͰ࣮૷͠ɺDaggerͰґଘΛղܾ͢Δ

    • λοϓϧͩͱRouterϞδϡʔϧʹΠϯλʔϑΣʔεΛ഑ஔɺ࣮૷͸ ֤FeatureϞδϡʔϧͰߦ͍ͬͯΔ