Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Migrate to Koin
Search
itome
December 13, 2018
370
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Migrate to Koin
itome
December 13, 2018
More Decks by itome
See All by itome
今日始め るCloudflare Browser Rendering
itome
2
340
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.6k
Introduce_Owl.pdf
itome
0
120
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
810
Introduction of accessibility for mobile development
itome
0
260
Architecture_for_mobile_development.pdf
itome
0
280
Android_Accessibility_Suite.pdf
itome
0
170
Introducing Owl
itome
0
1.2k
Featured
See All Featured
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
520
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.1k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
570
Crafting Experiences
bethany
1
250
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
400
The Cost Of JavaScript in 2023
addyosmani
55
10k
Documentation Writing (for coders)
carmenintech
77
5.4k
A Modern Web Designer's Workflow
chriscoyier
698
190k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
650
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
280
Transcript
Dagger͔ΒKoinʹΓ͑Δ Shibuya.apk #30
ࣗݾհ ௩ຊࢤ https://twitter.com/itometeam https://github.com/itome https://medium.com/@itometeam Cyberagent CATS 1min
Koinͱʁ 7min
Koinͱʁ 7min ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection!
ɾReady for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ // Add Jcenter to your repositories if needed
repositories { jcenter() } dependencies { // Koin for Android compile 'org.koin:koin-android:1.0.2' } Daggerͱಉ༷ʹAndroidݶఆϥΠϒϥϦͰͳ͍ͨΊɺ SparkKtorͳͲͷαʔόʔαΠυKotlinͰར༻Մೳ koin-androidϞδϡʔϧΛbuild.gradleʹهड़͢Δ͜ͱͰAndroidͰར༻Ͱ͖Δ υΩϡϝϯτ͕ॆ࣮͍ͯ͠ΔͷͰɺDIͷ֓೦Λཧղ͍ͯ͠Ε͙͢ʹ͍࢝ΊΒΕΔ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ val appModule = module { // single instance
of HelloRepository single<HelloRepository> { HelloRepositoryImpl() } // Simple Presenter Factory factory { MySimplePresenter(get()) } } moduleʹscopeؔΛهड़ͯ͠ґଘੑΛՃ͍ͯ͘͠ single: ΞϓϦέʔγϣϯͱಉ͡ϥΠϑαΠΫϧΛ࣋ͭΠϯελϯεΛ ࡞͢Δ ɻ factory: ඞཁʹͳΔͨͼʹผͷΠϯελϯεΛ࡞͢Δɻ scope: ΧελϜείʔϓΛఆٛͰ͖Δɻ Koinͱʁ 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ val appModule = module { // single instance
of HelloRepository single<HelloRepository> { HelloRepositoryImpl() } // Simple Presenter Factory factory { MySimplePresenter(get()) } } Koinͱʁ Daggerͱҧ͍ɺґଘάϥϑʹ͋ΔܕΛConstructor Injection͢Δ͚ͩͷ߹Ͱɺ ఆٛͷίʔυΛmoduleʹॻ͔ͳͯ͘ͳΒͳ͍ ͢Ͱʹґଘੑ͕ఆٛ͞Ε͍ͯΔΫϥε get()ͰऔಘͰ͖ΔͷͰɺ Constructor Injection͢Δͱ͖Ҿͷ͚ͩget()Λॻ͚ͩ͘Ͱ͍͍ 7min
ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ Koinͱʁ class MainApplication : Application() { override fun
onCreate() { super.onCreate() // start Koin context startKoin(this, listOf(appModule) } } ApplicationΫϥεͷonCreateͰ startKoin ʹModuleͷϦετΛ͢͜ͱͰ ґଘੑάϥϑ͕࡞͞ΕΔɻ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾno proxy, no code generation, no reflection! Koin࣮ࡍͷґଘੑͷೖΛKotlinͷDelegateΛ࣮ͬͯݱ͍ͯ͠ΔͨΊɺDaggerͷΑ͏ͳ ίʔυੜ͕ඞཁͳ͍
val appModule = module { single<Hello> { HelloServiceImpl(get()) } } class MyActivity : AppCompatActivity(){ val presenter : MyPresenter by inject() } ؔʹΑͬͯґଘੑͷೖ͕Ͱ͖ΔͨΊɺonCreateͳͲͰ໌ࣔతʹ inject injectΛݺͿඞཁ͕ͳ͍ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾReady for ViewModel AACͷViewModelΛσϑΥϧτͰαϙʔτ͍ͯ͠Δ class MyActivity : AppCompatActivity(){ //
Lazy inject MyViewModel val model : MyViewModel by viewModel() } ͷΘΓʹ by viewModel() by inject() Λ͏͜ͱͰ ViewModelProvider͔ΒViewModelͷΠϯελϯεΛऔಘͯ͘͠ΕΔ ಉҰͷActivityʹଐ͢ΔෳͷFragmentؒͰViewModelΛڞ༗͍ͨ͠ͱ͖ɺΘΓʹ by sharedViewModel() Λ͏ 7min
Koinͱʁ ɾKotlinͷܰྔDIϥΠϒϥϦ ɾno proxy, no code generation, no reflection! ɾReady
for ViewModel ɾKotlin DSLΛͬͨ؆ܿͳهड़Ͱґଘੑ͕هड़Ͱ͖Δ ɾEasy testing 7min
Koinͱʁ ɾEasy testing class MyTest : KoinTest { // Lazy
inject property val componentB : ComponentB by inject() @Test fun `should inject my components`() { startKoin(listOf(appModule))) // directly request an instance val componentA = get<ComponentA>() assertNotNull(a) assertEquals(componentA, componentB.a) } } KoinTestΛܧঝͨ͠ςετΫϥεͷதͰຊ൪ͱಉ༷ʹ startKoin ͕Ͱ͖Δ 7min
Koinͱʁ ɾEasy testing @Test fun `check module`() { checkModules(listOf(appModule))) }
Ϟδϡʔϧͷґଘੑ͕ղܾ͞Ε͍ͯΔ͔ͷςετͰ͖Δ 7min
Dagger → Koin 3min
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ೖͷͨͼʹΠϯελϯε࡞ Dagger
@Provides fun provideMyPresenter(): MyPresenter = … Koin factory { MyPresenter() }
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ΞϓϦέʔγϣϯ୯ҐͰڞ௨ͷΠϯελϯεΛ͏ Dagger
@Provides @Singleton fun provideRetrofit( okHttpClient: OkHttpClient ): Retrofit Koin single { Retrofit.Builder()… }
ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ 3min Dagger → Koin factory, single, scopeؔΛͬͯείʔϓΛ੍ޚ͢Δ ΧελϜείʔϓΛఆٛ Dagger
@Scope @Retention(AnnotationRetention.RUNTIME) annotation class ActivityScope @Subcomponent @ActivityScope interface MyActivitySubcomponent { ... } Koin scope(“MyActivity”) { … }
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾModuleΛ֊Խ͍ͨ͠ 3min Dagger → Koin Dagger @Subcomponent interface MyActivitySubcomponent {…}
@Module(subcomponents = MyActivitySubcomponet::class.java) class MyActivityModule {} @Component(modules = [MyActivityModule::class.java]) interface MyActivityComponent {…} Koin module("MyActivity") { module("MyActivitySub") { … } }
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾநΫϥεΛೖ͍ͨ͠ 3min Dagger → Koin Dagger @Binds fun bindUserApi( userApiClient:
UserApiClient ): UserApi Koin single { UserApiClient() } bind UserApi::class
Dagger → Koin 3min ɾDIͷείʔϓΛίϯτϩʔϧ͍ͨ͠ ɾநΫϥεΛೖ͍ͨ͠ ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ ɾModuleΛ֊Խ͍ͨ͠
ɾಉ͡ܕʹผͷΠϯελϯεΛೖ͍ͨ͠ 3min Dagger → Koin Dagger @Provides @Named("debug-client") fun provideDebugApiClient(retrofit:
Retrofit): ApiClient @Provides @Named("prod-client") fun provideProdApiClient(retrofit: Retrofit): ApiClient Koin single("debug-client") { ApiClient() } single("prod-client") { ApiClient() }
ϝϦοτɾσϝϦοτ 3min
ɾϝϦοτ 3min ϝϦοτɾσϝϦοτ Daggerʹൺͯґଘੑͷهड़ํ๏͕؆ܿͰɺΘ͔Γ͍͢ Field InjectionͷͨΊʹมΛpublicʹ͢Δඞཁ͕ͳ͍ AACͷViewModelͷInjectionʹରԠ͍ͯ͠Δ ίʔυੜΛߦΘͳ͍ͷͰɺίϯύΠϧ࣌ؒॖ͕ݟࠐΊΔ ϚϧνϞδϡʔϧϓϩδΣΫτͷಋೖ͕؆୯
ɾσϝϦοτ 3min ϝϦοτɾσϝϦοτ ґଘੑͷղܾΛίϯύΠϧ࣌ʹ͢ΔDaggerʹൺͯϥϯλΠϜ͕͍ ґଘੑͷॆʹࣦഊͨ͠ͱ͖ʹϥϯλΠϜΤϥʔͰམͪΔ͜ͱ͕͋Δ →ґଘੑͷॆʹ͍ͭͯςετ͕Ͱ͖ΔͨΊɺ൛Ͱى͜Δ֬Լ͛ΒΕΔ https://github.com/Sloy/android-dependency-injection-performance → moduleఆٛʹcreateOnStart=falseΛ͢͜ͱͰΠϯελϯεԽΛԆͰ͖Δ
·ͱΊ 1min
͋Γ͕ͱ͏͍͟͝·ͨ͠ Shibuya.apk #30 https://twitter.com/itometeam https://github.com/itome https://medium.com/@itometeam Cyberagent CATS ௩ຊ ࢤ