Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
130
droidknight_2018_nbt
hyunji92
0
62
devfest-AAC-2017-codelab
hyunji92
0
65
AAC-2017-soma
hyunji92
0
37
Other Decks in Programming
See All in Programming
実はマルチモーダルだった。ブラウザの組み込みAI🧠でWebの未来を感じてみよう #jsfes #gemini
n0bisuke2
3
1.3k
Basic Architectures
denyspoltorak
0
100
Grafana:建立系統全知視角的捷徑
blueswen
0
170
Implementation Patterns
denyspoltorak
0
110
DevFest Android in Korea 2025 - 개발자 커뮤니티를 통해 얻는 가치
wisemuji
0
170
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
180
実は歴史的なアップデートだと思う AWS Interconnect - multicloud
maroon1st
0
250
堅牢なフロントエンドテスト基盤を構築するために行った取り組み
shogo4131
8
2.5k
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
120
Deno Tunnel を使ってみた話
kamekyame
0
230
公共交通オープンデータ × モバイルUX 複雑な運行情報を 『直感』に変換する技術
tinykitten
PRO
0
160
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
160
Featured
See All Featured
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
260
Building an army of robots
kneath
306
46k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
100
Everyday Curiosity
cassininazir
0
110
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
140
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Side Projects
sachag
455
43k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
43
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
Practical Orchestrator
shlominoach
190
11k
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
য়ےदрٜয࣊ࢲ хࢎפ