DroidKaigi2019 Day 01 11:20~ 「マルチモジュールプロジェクトでの Dagger2を用いた Dependency Injection」 での発表資料です
サンプルコード https://github.com/kgmyshin/Multi-Module-Project-With-Dagger
X© DMM.comw %FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣw %BHHFS࠶ೖw %BHHFSͷ"OESPJEαϙʔτ࠶ೖw γϯάϧϞδϡʔϧͰͷ%BHHFSΛ༻͍ͨ%FQFOEFODZ*OKFDUJPOw ϚϧνϞδϡʔϧͰͷ%FQFOEFODZ*OKFDUJPOͷਏ͞w %BHHFSΛͬͯϚϧνϞδϡʔϧϓϩδΣΫτͰ%*Λ࣮ݱ͢Δw %ZOBNJD'FBUVSF.PEVMF͕͋Δ࣌ͷʢ͕࣌ؒ͋Εʣ"HFOEBΰʔϧϚϧνϞδϡʔϧͰߏ͞ΕͨϓϩδΣΫτͰɺ%BHHFSΛ༻͍ͨ%FQFOEFODZ*OKFDUJPOΛߦ͏ࡍͷΈϙΠϯτΛΓɺͦͷղܾࡦΛཧղ͢Δɻ
View Slide
!LHNZTIJO%SPJE,BJHJϚϧνϞδϡʔϧϓϩδΣΫτͰͷ%BHHFSΛ༻͍ͨ%FQFOEFODZ*OKFDUJPO
X© DMM.comࣗݾհw LHNZTIJOఝٶʢ͗͘Έʣw "OESPJEΤϯδχΞw ߹ಉձࣾ%..DPN$50ࣨॴଐ
X© DMM.com͜ͷηογϣϯͷΰʔϧ
X© DMM.com͜ͷηογϣϯͷΰʔϧϚϧνϞδϡʔϧͰߏ͞ΕͨϓϩδΣΫτͰɺ%BHHFSΛ༻͍ͨ%FQFOEFODZ*OKFDUJPOΛߦ͏ࡍͷΈϙΠϯτΛΓɺͦͷղܾࡦΛཧղ͢Δɻ
X© DMM.comBHFOEB
X© DMM.comBHFOEBw %FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣw %BHHFS࠶ೖw %BHHFSͷ"OESPJEαϙʔτ࠶ೖw γϯάϧϞδϡʔϧͰͷ%BHHFSΛ༻͍ͨ%FQFOEFODZ*OKFDUJPOw ϚϧνϞδϡʔϧͰͷ%FQFOEFODZ*OKFDUJPOͷਏ͞w %BHHFSΛͬͯϚϧνϞδϡʔϧϓϩδΣΫτͰ%*Λ࣮ݱ͢Δw %ZOBNJD'FBUVSF.PEVMF͕͋Δ࣌ͷ
X© DMM.comൃදʹೖΔલʹ͠ηογϣϯΛฉ͍ͯΔதͰɺΘ͔Βͳ͍ͱ͜ΖͳͲͰ͖ͯ·ͨ͠Βɺͥͻ%..DPNͷϒʔε·Ͱ͓ӽ͍ͩ͘͠͞ʂ
X© DMM.com%FQFOEFODZ*OKFDUJPOͱ
X© DMM.com%FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣҰݴͰɻʮґଘΦϒδΣΫτʯΛʮೖʯ͢ΔσβΠϯύλʔϯͰ͢ɻ
X© DMM.com%FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣinternal class AllergenRepositoryImpl: AllergenRepository {private val apiClient = ApiClient()override fun findAll(): Single> =apiClient.getAllergens()override fun findById(allergenId: AllergenId): Maybe =apiClient.getAllergen(allergenId.value)}%*͠ͳ͍
X© DMM.com%FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣinternal class AllergenRepositoryImpl @Injectconstructor(private val apiClient: ApiClient) : AllergenRepository {override fun findAll(): Single> =apiClient.getAllergens()override fun findById(allergenId: AllergenId): Maybe =apiClient.getAllergen(allergenId.value)}internal class AllergenRepositoryImpl: AllergenRepository {private val apiClient = ApiClient()override fun findAll(): Single> =apiClient.getAllergens()override fun findById(allergenId: AllergenId): Maybe =apiClient.getAllergen(allergenId.value)}%*͠ͳ͍ %*͢Δ
X© DMM.com%FQFOEFODZ*OKFDUJPOͱʢ؆୯ʹʣϝϦοτw ݁߹͕ૄʹͳΔw ୯ମςετ͕͍͢͠w ಛఆͷϥΠϒϥϦϑϨʔϜϫʔΫͷґଘΛԼ͛Δ͜ͱ͕Ͱ͖Δ
X© DMM.comಛఆͷϥΠϒϥϦϑϨʔϜϫʔΫͷґଘΛԼ͛Δ͜ͱ͕Ͱ͖Δw 7PMMFZPS3FUSPpUPS,UPS$MJFOUw 1JDBTTPPS(MJEFͳͲͳͲͷґଘΛ۩Օॴʹด͡ࠐΊΔ͜ͱͰɺ༰қʹϥΠϒϥϦΛΓସ͑Δ͜ͱ͕Ͱ͖Δɻ
X© DMM.comΑΓ͔ͬ͠ΓΓ͍ͨํʜ%BZdࠓ͔Β࢝ΊΔґଘੑͷೖCZLPCBLFJTBO
X© DMM.com%BHHFS࠶ೖ
X© DMM.comΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢Δʹʁ
X© DMM.comΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹʁΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹͲ͜ʹɹͳʹΛ*OKFDU͢Δ͔Λཏ͢Δඞཁ͕͋Δɻ
X© DMM.com%BHHFSͰΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹͲ͜ʹɹͳʹΛ*OKFDU͢Δ͔Λཏ͢Δඞཁ͕͋Δɻ
X© DMM.com%BHHFSͰ%FQFOEFODZ*OKFDUJPO͢Δ .PEVMFΛ༻ҙ͢Δ $PNQPOFOUΛ༻ҙ͢Δ "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ ֤ॴͰJOKFDU%BHHFSΛ࣮ͬͨͷྲྀΕ˞ɹखॱ̏߹ʹΑΔ͕ɺ͜͜Ͱ؆ུԽͷͨΊʹ͜ͷखॱʹݻఆ͢Δ˞ɹҎ߱ͷྫͰ'SBHNFOUͷ*OKFDUΛରͱ͍ͯ͠Δ͕ɺଞͷΫϥεʹஔ͖͑ͯͳ͍
X© DMM.comᶃ.PEVMFΛ༻ҙ͢Δ)PHFܕͷΠϯελϯεΛ͍ͩ͘͞IPHFΛͲ͏ͧʮͳʹΛఏڙ͢Δ͔ʁʯܕͱΠϯελϯεͷඥ͚Λߦ͏
X© DMM.comᶃ.PEVMFΛ༻ҙ͢Δ@Moduleinternal abstract class GreetingModule {@Bindsabstract fun provideGreeter(impl: GreeterImpl): Greeter}@Moduleinternal class CounterModule {@Singleton@Providesfun provideCounter(): Counter = CounterImpl()}.PEVMFͷॻ͖ํͷྫܕͱΠϯελϯεͷඥ͚Λߦ͏
X© DMM.comᶃ.PEVMFΛ༻ҙ͢Δ@Moduleinternal abstract class GreetingModule {@Bindsabstract fun provideGreeter(impl: GreeterImpl): Greeter}@Moduleinternal class CounterModule {@Singleton@Providesfun provideCounter(): Counter = CounterImpl()}.PEVMFͷॻ͖ํͷྫ
X© DMM.comᶄ$PNQPOFOUΛ༻ҙ͢ΔΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹͲ͜ʹɹͳʹΛ*OKFDU͢Δ͔Λཏ͢Δඞཁ͕͋Δɻ
X© DMM.comᶄ$PNQPOFOUΛ༻ҙ͢ΔΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹͲ͜ʹɹͳʹΛ*OKFDU͢Δ͔Λཏ͢Δඞཁ͕͋Δɻ$PNQPOFOUʹʮͳʹΛఏڙ͢Δ͔ʯҎ֎Λॻ͘
X© DMM.comᶄ$PNQPOFOUΛ༻ҙ͢ΔΞϓϦέʔγϣϯͰ%*Λ࣮ݱ͢ΔʹͲ͜ʹɹͳʹΛ*OKFDU͢Δ͔Λཏ͢Δඞཁ͕͋Δɻ$PNQPOFOUʹʮͳʹΛఏڙ͢Δ͔ʯҎ֎Λॻ͘ʮͲ͜ʹఏڙ͢Δ͔ʯΛओʹॻ͘
X© DMM.comᶄ$PNQPOFOUΛ༻ҙ͢Δ@Singleton@Component(modules = [GreetingModule::class])interface GreetingComponent {fun inject(activity: GreetingActivity)fun inject(fragment: GreetingFragment)fun greeter(): Greeter}$PNQPOFOUͷॻ͖ํͷྫJOKFDUઌΛҾʹͨؔ͠Λఆٛ͢Δ
X© DMM.comᶅ"QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽclass Application : android.app.Application(){lateinit var appComponent: AppComponentoverride fun onCreate() {super.onCreate()appComponent = DaggerAppComponent.create()}}
X© DMM.comᶆ֤ॴͰ*OKFDU͢Δclass MainFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {super.onAttach(context)(requireActivity().application as Application).appComponent.inject(this)}:}
X© DMM.com%BHHFS"OESPJE࠶ೖ
X© DMM.com%BHHFS"OESPJEͷϞνϕʔγϣϯclass MainFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {super.onAttach(context)(requireActivity().application as Application).appComponent.inject(this)}:}
X© DMM.com%BHHFS"OESPJEͷϞνϕʔγϣϯclass MainFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {super.onAttach(context)(requireActivity().application as Application).appComponent.inject(this)}:} *OKFDU͞ΕΔଆ͕ɺ*OKFDUPSʹ͍ͭͯͷৄࡉΛͬͯ͠·͍ͬͯΔɻ
X© DMM.com%BHHFS"OESPJEͷϞνϕʔγϣϯclass MainFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {super.onAttach(context)(requireActivity().application as Application).appComponent.inject(this)}:} *OKFDU͞ΕΔଆ͕ɺ*OKFDUPSʹ͍ͭͯͷৄࡉΛͬͯ͠·͍ͬͯΔɻͲ͜ʹ*OKFDUPS͕͋Δͷ͔ʁͲͷ*OKFDUPS͕ࣗΛ*OKFDUͰ͖Δͷ͔ʁͳͲ
X© DMM.com%BHHFS"OESPJEͷϞνϕʔγϣϯclass MainFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}:}͜͏͢Εɺྑͦ͞͏
X© DMM.comEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ .PEVMFΛ༻ҙ͢Δ $PNQPOFOUΛ༻ҙ͢Δ "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ ֤ॴͰJOKFDU%BHHFSΛ࣮ͬͨͷྲྀΕ
X© DMM.comEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ .PEVMFΛ༻ҙ͢Δ 'SBHNFOU.PEVMFΛ༻ҙ͢Δ /FX $PNQPOFOUΛ༻ҙ͢Δ 6QEBUFE "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ 6QEBUFE ֤ॴͰJOKFDU 6QEBUFEEBHHFSBOESPJEΛ࣮ͬͨͷྲྀΕ
X© DMM.comEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ .PEVMFΛ༻ҙ͢Δ 'SBHNFOU.PEVMFΛ༻ҙ͢Δ $PNQPOFOUΛ༻ҙ͢Δ "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ ֤ॴͰJOKFDUEBHHFSBOESPJEΛ࣮ͬͨͷྲྀΕ
X© DMM.comᶃ.PEVMFΛ༻ҙ͢Δ@Moduleabstract class AppModule {@Bindsabstract fun messageProvider(impl: MessageProviderImpl): MessageProvider}
X© DMM.comᶄ'SBHNFOU.PEVMFΛ༻ҙ͢Δ@Moduleabstract class MainFragmentModule {@ContributesAndroidInjectorabstract fun mainFragment(): MainFragment}
X© DMM.comᶅ$PNQPOFOUΛ༻ҙ͢Δ@Singleton@Component(modules = [AndroidInjectionModule::class,AppModule::class,MainFragmentModule::class])interface AppComponent : AndroidInjector
X© DMM.comᶅ$PNQPOFOUΛ༻ҙ͢Δ@Singleton@Component(modules = [AndroidInjectionModule::class,AppModule::class,MainFragmentModule::class])interface AppComponent : AndroidInjectorͲ͜ʹ*OKFDU͢Δ͔ɺ'SBHNFOU.PEVMF"OESPJE*OKFDUPSʹସ͞ΕͯΔͷͰॻ͔ͳ͍
X© DMM.comᶆ"QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽclass Application : android.app.Application(), HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector: DispatchingAndroidInjectoroverride fun supportFragmentInjector(): AndroidInjector =dispatchingFragmentInjectoroverride fun onCreate() {super.onCreate()DaggerAppComponent.create().inject(this)}}
X© DMM.comᶇ֤ॴͰ*OKFDUclass MainFragment : Fragment() {@Injectlateinit var messageProvider: MessageProvideroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}
X© DMM.comΈ$PNQPOFOUw .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏
X© DMM.comΈ$PNQPOFOUw .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏
X© DMM.comΈ$PNQPOFOUw .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏
X© DMM.comΈ$PNQPOFOUw .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏class Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector…DaggerAppComponent.create().inject(this)…}
X© DMM.comclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}Έ$PNQPOFOUw .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏w .BJO"DUJWJUZʹJOKFDU͢Δํ๏w 4VC"DUJWJUZʹJOKFDU͢Δํ๏w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏
X© DMM.comΈclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏
X© DMM.comΈclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏class MainFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}
X© DMM.comΈclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏class MainFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}class MainActivity : AppCompatActivity() {…}HasSupportFragmentInjectorΛ࣮ͯ͠Δ͔ʁ
X© DMM.comΈclass MainFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}class MainActivity : AppCompatActivity() {…}HasSupportFragmentInjectorΛ࣮ͯ͠Δ͔ʁclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏
X© DMM.comclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w .BJO'SBHNFOUʹJOKFDU͢Δํ๏w 4VC'SBHNFOUʹJOKFDU͢Δํ๏Έclass MainFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}class MainActivity : AppCompatActivity() {…}HasSupportFragmentInjectorΛ࣮ͯ͠Δ͔ʁ
X© DMM.comϚϧνϞδϡʔϧͷ%*Ͱͷਏ͞
X© DMM.comϚϧνϞδϡʔϧͰͷ%*BQQDPVOUFS HSFFUJOH͜͏͍͏ͷΛ࡞Δ
X© DMM.comϚϧνϞδϡʔϧͰͷ%*͜͏͍͏ͷΛ࡞ΔBQQDPVOUFS HSFFUJOH$PNQPOFOUͦΕͧΕͰ࣋ͭ
X© DMM.comEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ .PEVMFΛ༻ҙ͢Δ 'SBHNFOU.PEVMFΛ༻ҙ͢Δ $PNQPOFOUΛ༻ҙ͢Δ "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ ֤ॴͰJOKFDUࠓ·Ͱͱಉ͡खॱͰɺEBHHFSBOESPJEΛ࣮ͬͯͯ͠ΈΔ
X© DMM.comᶆ"QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽclass Application : HasSupportFragmentInjector, … {@Injectlateinit var dispatchingFragmentInjector DispatchingAndroidInjector()override fun supportFragmentInjector(): AndroidInjector =dispatchingFragmentInjectoroverride fun onCreate() {super.onCreate()DaggerCounterComponent.create().inject(this)DaggerGreetingComponent.create().inject(this)…}}
X© DMM.comᶇ֤ॴͰ*OKFDUclass CounterFragment : Fragment() {@Injectlateinit var counter: Counteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}class GreetingFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}
X© DMM.comͲ͏ͳΔ͔ʁ$PVOUFS'SBHNFOU (SFFUJOH'SBHNFOU
X© DMM.com$PNQPOFOUΛॳظԽͷॱ൪ΛೖΕସ͑ͯΈΔͱclass Application : HasSupportFragmentInjector, … {@Injectlateinit var dispatchingFragmentInjector DispatchingAndroidInjector()override fun supportFragmentInjector(): AndroidInjector =dispatchingFragmentInjectoroverride fun onCreate() {super.onCreate()DaggerCounterComponent.create().inject(this)DaggerGreetingComponent.create().inject(this)…}}
X© DMM.com$PNQPOFOUΛॳظԽͷॱ൪ΛೖΕସ͑ͯΈΔͱclass Application : HasSupportFragmentInjector, … {@Injectlateinit var dispatchingFragmentInjector DispatchingAndroidInjector()override fun supportFragmentInjector(): AndroidInjector =dispatchingFragmentInjectoroverride fun onCreate() {super.onCreate()DaggerGreetingComponent.create().inject(this)DaggerCounterComponent.create().inject(this)…}}
X© DMM.com$SBTI͢Δཧ༝class Application : HasSupportFragmentInjector, … {@Injectlateinit var dispatchingFragmentInjector DispatchingAndroidInjector()…override fun onCreate() {super.onCreate()DaggerCounterComponent.create().inject(this)DaggerGreetingComponent.create().inject(this)…}}
X© DMM.comclass Application : HasSupportFragmentInjector {@Injectlateinit var dispatchingFragmentInjector}w (SFFUJOH'SBHNFOUʹJOKFDU͢Δํ๏Έclass CounterFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}
X© DMM.com%BHHFSΛͬͯϚϧνϞδϡʔϧϓϩδΣΫτͰ%*Λ࣮ݱ͢Δ
X© DMM.comվΊͯ՝ͱʁ՝"QQMJDBUJPOʹ'SBHNFOU༻ͷ*OKFDUPSΛҰ͔ͭ࣋ͯ͠ͳ͍ͨΊʹɺ*OKFDUPS্͕ॻ͖͞Εͯ͠·͏͜ͱ
X© DMM.com"QQMJDBUJPOͰ࣋ͭͭͷ'SBHNFOU*OKFDUPS͕ɺෳͷ*OKFDUPSΛ࣋ͭΑ͏ʹ͢ΔղܾࡦͷҰͭ
X© DMM.comͭͷ*OKFDUPSͷதͰෳͷ*OKFDUPSΛ࣋ͭΑ͏ʹ͢Δ
X© DMM.comclass ModuleInjector : AndroidInjector {private val injectors = mutableListOf>()fun addInjector(injector: HasDispatchingInjector) {injectors.add(injector)}fun removeInjector(injector: HasDispatchingInjector) {injectors.remove(injector)}…override fun inject(instance: T) {val wasInjected = injectors.any { it.dispatchingAndroidInjector().maybeInject(instance) }if (!wasInjected) {throw IllegalArgumentException("injection failed")}}}.PEVMF*OKFDUPS
X© DMM.comclass ModuleInjector : AndroidInjector {private val injectors = mutableListOf>()fun addInjector(injector: HasDispatchingInjector) {injectors.add(injector)}fun removeInjector(injector: HasDispatchingInjector) {injectors.remove(injector)}…override fun inject(instance: T) {val wasInjected = injectors.any { it.dispatchingAndroidInjector().maybeInject(instance) }if (!wasInjected) {throw IllegalArgumentException("injection failed")}}}.PEVMF*OKFDUPSinterface HasDispatchingInjector {fun dispatchingAndroidInjector(): DispatchingAndroidInjector}
X© DMM.comEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ NVMUJNPEVMF .PEVMFΛ༻ҙ͢Δ 'SBHNFOU.PEVMFΛ༻ҙ͢Δ *OKFDUPSΛ༻ҙ͢Δ /FX $PNQPOFOUΛ༻ҙ͢Δ 6QEBUFE "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ 6QEBUFE ֤ॴͰJOKFDUࠓ·Ͱͱಉ͡खॱͰɺEBHHFSBOESPJEΛ࣮ͬͯͯ͠ΈΔ
X© DMM.com .PEVMFΛ༻ҙ͢Δ 'SBHNFOU.PEVMFΛ༻ҙ͢Δ *OKFDUPSΛ༻ҙ͢Δ $PNQPOFOUΛ༻ҙ͢Δ "QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ ֤ॴͰJOKFDUࠓ·Ͱͱಉ͡खॱͰɺEBHHFSBOESPJEΛ࣮ͬͯͯ͠ΈΔEBHHFSBOESPJEͰ%FQFOEFODZ*OKFDUJPO͢Δ NVMUJNPEVMF
X© DMM.comᶃ.PEVMFΛ༻ҙ͢Δ@Moduleinternal abstract class CounterModule {@Singleton@Bindsabstract fun provideCounter(impl: CounterImpl): Counter}@Moduleinternal abstract class GreetingModule {@Bindsabstract fun provideGreeter(impl: GreeterImpl): Greeter}
X© DMM.comᶄ'SBHNFOU.PEVMFΛ༻ҙ͢Δ@Moduleinternal abstract class GreetingFragmentModule {@ContributesAndroidInjectorabstract fun greetingFragment(): GreetingFragment}@Moduleinternal abstract class CounterFragmentModule {@ContributesAndroidInjectorabstract fun counterFragment(): CounterFragment}
X© DMM.comᶅ*OKFDUPSΛ༻ҙ͢Δclass CounterInjector : HasDispatchingInjector {@Injectlateinit var supportFragmentInjector: DispatchingAndroidInjectoroverride fun dispatchingAndroidInjector(): DispatchingAndroidInjector =supportFragmentInjector}class GreetingInjector : HasDispatchingInjector {@Injectlateinit var supportFragmentInjector: DispatchingAndroidInjectoroverride fun dispatchingAndroidInjector(): DispatchingAndroidInjector =supportFragmentInjector}
X© DMM.comᶆ$PNQPOFOUΛ༻ҙ͢Δ@Singleton@Component(modules = [AndroidInjectionModule::class,CounterModule::class,CounterFragmentModule::class])interface CounterComponent : AndroidInjector@Singleton@Component(modules = [AndroidInjectionModule::class,GreetingModule::class,GreetingFragmentModule::class])interface GreetingComponent : AndroidInjector
X© DMM.comᶇ"QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ͢Δclass Application : android.app.Application(), HasSupportFragmentInjector {private val fragmentInjector = ModuleInjector()override fun supportFragmentInjector(): AndroidInjector = fragmentInjectoroverride fun onCreate() {super.onCreate()val counterInjector = CounterInjector()DaggerCounterComponent.create().inject(counterInjector)val greetingInjector = GreetingInjector()DaggerGreetingComponent.create().inject(greetingInjector)fragmentInjector.addInjector(counterInjector)fragmentInjector.addInjector(greetingInjector)}}
X© DMM.comclass Application : android.app.Application(), HasSupportFragmentInjector {private val fragmentInjector = ModuleInjector()override fun supportFragmentInjector(): AndroidInjector = fragmentInjectoroverride fun onCreate() {super.onCreate()val counterInjector = CounterInjector()DaggerCounterComponent.create().inject(counterInjector)val greetingInjector = GreetingInjector()DaggerGreetingComponent.create().inject(greetingInjector)fragmentInjector.addInjector(counterInjector)fragmentInjector.addInjector(greetingInjector)}}ᶇ"QQMJDBUJPOPO$SFBUFͰ$PNQPOFOUΛॳظԽ͢Δ
X© DMM.comᶈ֤ॴͰ*OKFDUclass CounterFragment : Fragment() {@Injectlateinit var counter: Counteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}class GreetingFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}
X© DMM.comྲྀΕ
X© DMM.comྲྀΕclass Application :…, HasSupportFragmentInjector {private val moduleFragmentInjector…}
X© DMM.comྲྀΕclass Application :…, HasSupportFragmentInjector {private val moduleFragmentInjector…}class CounterFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}
X© DMM.comྲྀΕclass Application :…, HasSupportFragmentInjector {private val moduleFragmentInjector…}class CounterFragment : Fragment() {ɹɹ…AndroidSupportInjection.inject(this)…}class MainActivity : AppCompatActivity() {…}HasSupportFragmentInjectorΛ࣮ͯ͠Δ͔ʁ
X© DMM.com%ZOBNJD'FBUVSF.PEVMF
X© DMM.com%ZOBNJD'FBUVSF.PEVMF͕͋Δ࣌ͷ%*BQQDPVOUFS HSFFUJOH͍··Ͱ
X© DMM.com%ZOBNJD'FBUVSF.PEVMF͕͋Δ࣌ͷ%*BQQDPVOUFSHSFFUJOHHSFFUJOHΛEZOBNJDGFBUVSFʹBQQDPVOUFS HSFFUJOH͍··Ͱ
X© DMM.com"QQMJDBUJPOPO$SFBUFҎ߱ͷదͳλΠϛϯάͰJOKFDUPSΛੜͯ͠ɺNPEVMF*OKFDUPSʹՃ͢ΔղܾࡦͷҰͭ
X© DMM.comͨͱ͑ɺ͜ΜͳؔΛ࡞Δobject GreetingInjection {fun inject(fragment: Fragment) {val application = fragment.requireActivity().application as Applicationif (application.moduleFragmentInjector.injectors().all { it !is GreetingInjector }) {val injector = GreetingInjector()val component =DaggerGreetingComponent.builder().counter(application.counterComponent().counter()).build()component.inject(injector)application.addFragmentInjector(injector)}AndroidSupportInjection.inject(fragment)}}
X© DMM.comͨͱ͑ɺ͜ΜͳؔΛ࡞Δobject GreetingInjection {fun inject(fragment: Fragment) {val application = fragment.requireActivity().application as Applicationif (application.moduleFragmentInjector.injectors().all { it !is GreetingInjector }) {val injector = GreetingInjector()val component =DaggerGreetingComponent.builder().counter(application.counterComponent().counter()).build()component.inject(injector)application.addFragmentInjector(injector)}AndroidSupportInjection.inject(fragment)}} "DUJWJUZʹNPEVMF*OKFDUPS͕͋Δ߹Λߟྀͯ͠ɺ"OESPJE4VQQPSU*OKFDUJPOͱಉ͡Α͏ͳ࣮ʹ͢ΔͷՄ
X© DMM.comͨͱ͑ɺ͜ΜͳؔΛ࡞Δobject GreetingInjection {fun inject(fragment: Fragment) {val application = fragment.requireActivity().application as Applicationif (application.moduleFragmentInjector.injectors().all { it !is GreetingInjector }) {val injector = GreetingInjector()val component =DaggerGreetingComponent.builder().counter(application.counterComponent().counter()).build()component.inject(injector)application.addFragmentInjector(injector)}AndroidSupportInjection.inject(fragment)}} ˞"DUJWJUZͰ*OKFDUPSΛ࣋ͭͱ͖͜ͷํ๏ͩͱ͏·͍͔͘ͳ͍ͷͰ݅ذ͢Δඞཁ͕͋Γ·͢ʂ
X© DMM.comͦ͏͢ΔͱɺJOKFDUઌ͜ͷมߋ͚ͩͰࠓ·Ͱ௨Γಈ͘Α͏ʹͳΔclass GreetingFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {GreetingInjection.inject(this)super.onAttach(context)}…}class GreetingFragment : Fragment() {@Injectlateinit var greeter: Greeteroverride fun onAttach(context: Context?) {AndroidSupportInjection.inject(this)super.onAttach(context)}…}
X© DMM.comͨ͜͠ͱৼΓฦΓ
X© DMM.comͨ͜͠ͱৼΓฦΓw %FQFOEFODZ*OKFDUJPOͱw %BHHFSͷ͍ํͷҰྫɺखॱɺΈw %BHHFS"OESPJEαϙʔτͷ͍ํͷҰྫɺखॱɺΈw ͦͷ··ͰϚϧνϞδϡʔϧରԠͰ͖ͳ͍έʔε͕͋Δ͜ͱw .PEVMF*OKFDUPSΛಋೖ͢Δ͜ͱͰରԠͰ͖Δ͜ͱw %ZOBNJD'FBUVSF.PEVMF࣌ɺదͳλΠϛϯάͰ*OKFDUPSΛ.PEVMF*OKFDUPSʹࠩ͠ࠐΜͰ͋͛Δඞཁ͕͋Δ͜ͱ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠