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
How to use Dagger2 and Koin
Search
Hyeonji Jeong
April 05, 2019
Programming
2
1.1k
How to use Dagger2 and Koin
2019_정현지_droidknights
Dagger2 vs Koin 어떻게 쓰는 걸까요?
Hyeonji Jeong
April 05, 2019
Tweet
Share
More Decks by Hyeonji Jeong
See All by Hyeonji Jeong
2018 DevFest - Update to Oreo & Pie
hyunji92
0
120
droidknight_2018_nbt
hyunji92
0
62
devfest-AAC-2017-codelab
hyunji92
0
63
AAC-2017-soma
hyunji92
0
37
Other Decks in Programming
See All in Programming
A full stack side project webapp all in Kotlin (KotlinConf 2025)
dankim
0
110
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.5k
Goで作る、開発・CI環境
sin392
0
220
猫と暮らす Google Nest Cam生活🐈 / WebRTC with Google Nest Cam
yutailang0119
0
110
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
1
9.1k
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
120
git worktree × Claude Code × MCP ~生成AI時代の並列開発フロー~
hisuzuya
1
550
技術同人誌をMCP Serverにしてみた
74th
1
630
WebViewの現在地 - SwiftUI時代のWebKit - / The Current State Of WebView
marcy731
0
110
ふつうの技術スタックでアート作品を作ってみる
akira888
1
490
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
730
LINEヤフー データグループ紹介
lycorp_recruit_jp
1
2.4k
Featured
See All Featured
Fireside Chat
paigeccino
37
3.5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
For a Future-Friendly Web
brad_frost
179
9.8k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.4k
Embracing the Ebb and Flow
colly
86
4.7k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
960
Speed Design
sergeychernyshev
32
1k
BBQ
matthewcrist
89
9.7k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Transcript
%BHHFS WT ,PJO যڌѱॳחѦөਃ 4QFBLFS അ
ٜٜ۠࠙ਵदݶજणפ %BHHFS৬,PJOӝୡੋधҗद ਊߨਸঌҊरযೞחפযٜ࠙ਸਤೠ ߊܳೞ۰Ҋפ
য়טݾର ↟%*ۆޖੌө ↟%BHHFSۆޖੌө ↟,PJOۆޖੌө ↟%BHHFS৬,PJO җױޖੌө
↟ۧѱࢎਊ೧ࠁ ↟%BHHFS,PJOਊ೧ࠁӝ ↟ޖܻ۽ંী؊যܾө ↟%*ܳҕࠗೞҊۧѱਊೞݶܻоחѪޖੌө ↟݃ޖܻ
%*ۆޖੌө %FQFOEFODZ*OKFDUJPO
%*ۆޖੌө %FQFOEFODZ*OKFDUJPO
%*ۆޖੌө %FQFOEFODZ $MBTT$PGGFF GVONBLF-BUUF $MBTT.BUFSJBM GVONJML GVOFTQSFTTP
%*ۆޖੌө %FQFOEFODZ class Coffee { val material = Material() fun
makeLatte() { material.milk() material.espresso() } } class Material { fun milk() {} fun espresso() {} }
%*ۆޖੌө %FQFOEFODZ*OKFDUJPO
%*ۆޖੌө Ӓܿ߸҃ OFX.JML -BUUFё OFX&TQSFTTP Latte ё
উীࢲ ࢜۽ ёܳ ࢤࢿೞ ঋח!
%*ۆޖੌө فѐ࢚ݽٕաېझрѾبܳծ୶ӝਤ೧ ৻ࠗীࢲOFXёࢤࢿਸೞҊੑೞחѪ %* ઓࢿੑۆ
-BUUFё OFX4ZSVQ OFX.JML OFX&TQSFTTP
OFX*DF %*ۆޖੌө
-BUUFё OFX4ZSVQ OFX.JML OFX&TQSFTTP
OFX*DF %*ۆޖੌө "NFSJDBOPё OFX4ZSVQ OFX&TQSFTTP OFX*DF
%*ۆޖੌө OFX.JML -BUUFё OFX &TQSFTTP OFX4ZSVQ OFX*DF
%*ۆޖੌө OFX.JML -BUUFё OFX &TQSFTTP OFX4ZSVQ OFX*DF
"NFSJDBOPё
%*ۆޖੌө *0$ ৻ࠗ'SBNFXPSL OFX.JML OFX &TQSFTTP OFX4ZSVQ
OFX*DF -BUUFё
%BHHFSۆޖੌө
%BHHFSۆޖੌө উ٘۽٘ীࢲ ઓࢿੑਸҳഅೞӝਤ೧ ࢎਊೞחۄ࠳۞ܻ
ਫ਼Ӭ݅ঌҊֈযо %BHHFS %BHHFS
ਫ਼Ӭ݅ঌҊֈযо %BHHFS 4RVBSF %BHHFS (PPHMF
ਫ਼Ӭ݅ঌҊֈযо ਫ਼Ӭ݅ঌҊֈযо %BHHFS 3FGMFDUJPOוܻ ۠ఋ(SBQIҳࢿ
द
%BHHFSۆޖੌө
%BHHFSۆޖੌө ↟%FQFOEFODZJOKFDUJPOUPPM ↟BOOPUBUJPOQSPDFTTPSࢎਊ ↟OPSVOUJNFFSSPS ↟ࣽࣻ+BWB۽ܖয ↟OPSFGMFDUJPONPSFGBTU ↟੍ӝएHFOFSBUFEDPEF ↟QSPHVBSEࢸਃহ
%BHHFSۆޖੌө %BHHFSࣻѐ֛ *OKFDU $PNQPOFOU 4VCDPNQPOFOU .PEVMF 4DPQF 1SPWJEFT
%BHHFSۆޖੌө рױೞѱ !NPEVMF ҕә !$PNQPOFOU োѾ೧חઁҕ !*OKFDU ੑ߉חࣗ࠺
ಕۄڍٜܳ݅যࠅөਃ FTQSFTTP DPGGFF NJML -BUUFё
%FQFOEFODZ(SBQI " $ % #
ಕۄڍٜܳ݅যࠅөਃ FTQSFTTP DPGGFF NJML -BUUFё
%BHHFSۆޖੌө ઁ class Milk class Espresso class Coffee(var espresso: Espresso)
class Latte @Inject constructor( var coffee: Coffee, var milk: Milk) { fun makeLatteDrink() {} }
%BHHFSۆޖੌө ઁ @Module public class DrinkModule { @Provides Milk ProvideMilk(){
return Milk () } @Provides Espresso ProvideEspresso(){ return Espresso () } @Provides Coffee ProvideCoffee( var espresso: Espresso){ return Coffee (espresso) } }
%BHHFSۆޖੌө ઁ @Component(modules = {DrinkModule::class}) public interface DrinkComponent { fun
drink(): Latte fun inject(Activity: MainActivity) }
%BHHFSۆޖੌө ઁ class MainActivity : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) val latteComponent = DaggerDrinkComponent.builder() .drinkModule(DrinkModule()) .build() latteComponent.inject(this) latteComponent.drink() }
ಕۄڍٜܳ݅যࠅөਃ FTQSFTTP DPGGFF NJML -BUUFё
None
,PJOۆޖੌө ,PUMJOਸࢎਊೞחѐߊٜਸਤೠ पਊੋ"1*ઁҕਸೞח ҃ചػઓࢿੑۨਕ
,PJOۆޖੌө ↟4FSWJDF-PDBUPS1BUUFSOҳഅ ↟LPUMJO%4- بݫੋౠযࢎਊ ↟OPSFGMFDUJPO ↟QVSFLPUMJOਵ۽ܖযઉ
ਫ਼Ӭ 4FSWJDF-PDBUPS1BUUFSOਃj
,PJOۆޖੌө FTQSFTTP NJML NBUFSJBMT -PDBUPS 4FSWJDF-PDBUPS1BUUFSO ,PJOۆޖੌө
,PJOۆޖੌө ਫ਼Ӭ%4-ਃj
ಕۄڍٜܳ݅যࠅөਃ ,PJOۆޖੌө FTQSFTTP NJML NBUFSJBMT -PDBUPS
NPEVMF GBDUPSZ TJOHMF BMTPBMJBTFEBTCFBO CJOE
HFU TDPQF ,PJOࣻѐ֛ ,PJOۆޖੌө
,PJOۆޖੌө ઁ class Milk class Espresso class Coffee(var espresso: Espresso)
class Latte(var coffee: Coffee, var milk: Milk) { fun makeLatteDrink() {} }
,PJOۆޖੌө ઁ class MainApplication: Application() { override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) //start koin startKoin(this, listOf(myModules)) } } val myModules = module { single { Milk() } single { Espresso() } single { Coffee(get()) } single { Latte(get(), get())} }
,PJOۆޖੌө ઁ inline fun <reified T> get( qualifier: Qualifier? =
null, scope: Scope = this, noinline parameters: ParametersDefinition? = null ): T { return getKoin().get(T::class, qualifier, scope, parameters) ?: error("$this is not registered - Koin is null") }
,PJOۆޖੌө ઁ <reified T> SFJGJFEGVODUJPO
,PJOۆޖੌө ઁ inline fun <reified T> get( qualifier: Qualifier? =
null, scope: Scope = this, noinline parameters: ParametersDefinition? = null ): T { return getKoin().get(T::class, qualifier, scope, parameters) ?: error("$this is not registered - Koin is null") }
,PJOۆޖੌө ઁ class MainActivity : AppCompatActivity(){ val latte: Latte by
inject() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val latte: Latte = get() }
%BHHFS৬,PJO җױޖੌө
↟SFGMFDUJPOਸࢎਊೞঋ ↟য֢ప࣌ࢎਊਵ۽рױೠ٘ࢶ ↟ҕਬغחੋझఢझӔਸױࣽച ↟ࠂೠઓࢿएജ҃ࢸ ↟एਬాపझ %BHHFS
↟۞ழ࠳о֫ ↟৮߷ೠಌಖઁоহ ↟ઓҙ҅ীೠ٘ۨఊয۵ ↟য֢ప࣌ӝ߈ۄஹੌदрטযդ ஹੌয়ߡ٘ ↟݆ஹನք৬݆ੌਃ %BHHFSױ
↟য֢ప࣌җহযஹੌࡅܴ ↟णҗࢸऔ ↟,PUMJO%4-ࢎਊ ,PJO
↟۠ఋী۞оߊࢤ ↟࢜۽যܳߓਕঠೣ ↟ઁܳӝ൨ٞ ,PJOױ
Ӓېࢲ۽যڌѱࢎਊೞחѤؘਃ
ۧѱࢎਊ೧ࠁ ઁ(JUIVCਬѨ࢝ (JU)VC6TFS4FBSDI"1*ࢎਊ IUUQTEFWFMPQFSHJUIVCDPNWTFBSDI
ۧѱࢎਊ೧ࠁ%BHHFS @Singleton class GithubUserApiClient constructor( provideOkHttpClient: OkHttpClient) { var baseUrl
= "https://api.github.com" val userDataService: GithubUserApiService init { val retrofit = Retrofit.Builder() .baseUrl(baseUrl) .client(provideOkHttpClient) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() userDataService = retrofit.create(GithubUserApiService::class.java) } }
ۧѱࢎਊ೧ࠁ%BHHFS @Module class ApiClientModule { @Provides fun provideOkHttpClient(): OkHttpClient {
val logging = HttpLoggingInterceptor() logging.level = HttpLoggingInterceptor.Level.BASIC return OkHttpClient.Builder() .addInterceptor(logging) .build() } @Provides fun provideGithubUserApiClient(): GithubUserApiClient { return GithubUserApiClient(provideOkHttpClient()) } }
ۧѱࢎਊ೧ࠁ%BHHFS @Module(includes = [ApiClientModule::class]) class GithubUserListModule(val view: MainPresenter.View) { @Provides
fun provideMainPresenter( presenter: MainPresenterImpl) : MainPresenter { return presenter } @Provides fun provideMainView(): MainPresenter.View { return view } }
ۧѱࢎਊ೧ࠁ%BHHFS @Component(modules = [GithubUserListModule::class]) interface GithubUserListComponent { fun inject(Activity: MainActivity)
}
ۧѱࢎਊ೧ࠁ%BHHFS class MainPresenterImpl @Inject constructor( val view: MainPresenter.View, val client:
GithubUserApiClient) : MainPresenter { @SuppressLint("CheckResult") override fun getGithubUserList(q: String) { client.userDataService.getUserData(q, "repositories", "desc") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({view.onDataLoaded(it)},{view.onDataFailed()},{}) } }
ۧѱࢎਊ೧ࠁ%BHHFS class MainActivity : AppCompatActivity(), MainPresenter.View { @Inject lateinit var
presenter: MainPresenter override fun searchGithubUser(searchWord: String) { if (searchWord.isNullOrBlank()) { toast("Ѩ࢝ػ о হणפ") userFragment.userAdapter.apply { items.clear() notifyDataSetChanged() } } else { presenter.getGithubUserList(searchWord) } } ... }
ۧѱࢎਊ೧ࠁ%BHHFS override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) //initialize
AppComponent var component = DaggerGithubUserListComponent.builder() .githubUserListModule(GithubUserListModule(this)) .build() component.inject(this) .. }
ۧѱࢎਊ೧ࠁ%BHHFS @Module(includes = [ApiClientModule::class]) class GithubUserListModule(val view: MainPresenter.View) { @Provides
fun provideMainPresenter( presenter: MainPresenterImpl) : MainPresenter { return presenter } @Provides fun provideMainView(): MainPresenter.View { return view } }
ۧѱࢎਊ೧ࠁزੌೠӝמઁ ઁ(JUIVCਬѨ࢝ (JU)VC6TFS4FBSDI"1*ࢎਊ IUUQTEFWFMPQFSHJUIVCDPNWTFBSDI
ۧѱࢎਊ೧ࠁ,PJO val userlistModule: Module = module { factory { MainPresenterImpl(get())
as MainPresenter<*> } }
ۧѱࢎਊ೧ࠁ,PJO val apiModule: Module = module { single { val
loggingInterceptor = HttpLoggingInterceptor() if (BuildConfig.DEBUG) { loggingInterceptor.level = HttpLoggingInterceptor.Level.BASIC } else { loggingInterceptor.level = HttpLoggingInterceptor.Level.NONE } Retrofit.Builder() .baseUrl("https://api.github.com") .client(OkHttpClient.Builder().addInterceptor(loggingInterceptor).build()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() .create(GithubUserApiService::class.java) } } val appModules = listOf(apiModule, userlistModule)
ۧѱࢎਊ೧ࠁ,PJO class MainApplication :Application() { override fun onCreate() { super.onCreate()
startKoin { // Android context androidContext(this@MainApplication) // modules modules(appModules) } } }
ۧѱࢎਊ೧ࠁ,PJO lass MainActivity : AppCompatActivity(), UserDataList { private val presenter:
MainPresenter<UserData> by inject() override fun searchGithubUser(searchWord: String) { if (searchWord.isNullOrBlank()) { presenter.getGithubUserList("a") userFragment.userAdapter.apply { items.clear() notifyDataSetChanged() } } else { presenter.getGithubUserList(searchWord) } } ... }
ۧѱࢎਊ೧ࠁ,PJO override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) presenter.userData
= this ... }
ࣁೠ٘ח(JUIVCীj IUUQTHJUIVCDPNIZVOKJ 'JOE/FX6TFST
ޖܻ۽ંী؊যܾө
%*ܳ൨ٜѱҕࠗ೧ࢲਊ೧оҊ ܻ۽ંӒܻҊܻਗٜ חҗোޖੋо
ઓࢿࢎਊਵ۽ח
↟୶࢚ചܳా೧ػёٜ࢚ഐਊী೧زੋܴоמ ↟۠ఋী߄ੋ٬غযઓࢿ৻ࠗীࢲੑغযઓبܳծ୶Ҋࢎਊоמ ↟ੑػ٘ӝמਸ߄ԲҊरਸٸ ݆٘ܳ߄Եਃоহ ↟ࢤࢿػੋझఢझझ ੋझఢࢤࢿҗࢤݺӝܳ %*ۨਕীࢲঌইࢲ೧ળ ઓࢿࢎਊਵ۽ח
݃ޖܻ Ӓېࢲަॳݶજױ݈ջ
݃ޖܻ ࢎप
݃ޖܻ ࢶఖীח଼ٮܲj
য়ےदрٜয࣊ࢲ хࢎפ