Skip to content

Instantly share code, notes, and snippets.

@kettsun0123
Created October 4, 2017 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kettsun0123/936622907ab5df6f06ca867191115d8a to your computer and use it in GitHub Desktop.
Save kettsun0123/936622907ab5df6f06ca867191115d8a to your computer and use it in GitHub Desktop.
Kodein使ってみた
package xyz.kettsun.githubbrowser
import android.app.Application
import com.github.salomonbrys.kodein.*
import com.github.salomonbrys.kodein.android.autoAndroidModule
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import xyz.kettsun.githubbrowser.action.GithubAction
import xyz.kettsun.githubbrowser.api.GithubApi
import xyz.kettsun.githubbrowser.api.GithubApiClient
import xyz.kettsun.githubbrowser.dispatcher.Dispatcher
import xyz.kettsun.githubbrowser.store.GithubStore
/**
* 簡易的にApplicationでDIを定義
* Created by Yuji Koketsu on 2017/10/04.
*/
class App : Application(), KodeinAware { //KodeinAwareをimplementして,kodeinのinstanceを持っておく
override val kodein: Kodein by Kodein.lazy {
import(autoAndroidModule(this@App)) // Android
bind<Interceptor>() with instance(HttpLoggingInterceptor())
// 本来↑はHttpInterceptorにしたいが,OkHttpClient.Builder()のaddNetworkInterceptorがInterceptorを受け取るようになっていて,KODEINは継承元でキャストしてくれないためこうしている
bind<OkHttpClient>() with singleton { OkHttpClient.Builder().addNetworkInterceptor(instance()).build()}
bind<Retrofit>() with singleton {
Retrofit.Builder()
.client(instance())
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
bind<GithubApi>() with provider { GithubApiClient(instance()) }
bind<Dispatcher>() with singleton { Dispatcher() }
bind<GithubAction>() with singleton { GithubAction(instance(), instance()) }
bind<GithubStore>() with singleton { GithubStore(instance()) }
}
}

Kodein

業務でAndroid開発にてKotlinを触ることになったので,せっかくだからKotlin純正のDIコンテナKodeinを触ってみることにしました, 簡単なGithubのリポジトリをリスト表示するサンプルアプリを作ったので,書き方と注意点を記録に残しておきます.

間違っているところもあるかもしれないので,ご意見ご指摘はあればどしどしお待ちしております.

Kodeinとは

Kodein is a very useful dependency retrieval container, it is very easy to use and configure.

KodeinのGithubページから引用.簡単に言うと

めっちゃ簡単にDI実現できるコンテナだよ

ということですね.

Kodeinは本当にシンプルで,追加のメソッドを生成しない,kaptを使用せずにDIコンテナを提供しています.

Kodeinの導入

Androidのgradleに

dependencies {
  implementation 'com.github.salomonbrys.kodein:kodein:4.1.0'
  implementation 'com.github.salomonbrys.kodein:kodein-android:4.1.0'
}

を追記して,SyncすればKodeinが使えます.簡単:)

DIの定義

基本的なbinding

DIの定義は,Kodein {...}ブロックに書きます.もしくは,Kodein.Module {...}でも構いません. 各々書くべき場所は限定されていないので,ファイルを作成して直下に

fun networkModule() = Kodein.Module {
...
}

と定義しても構いません.今回は簡易のためApp.ktにまるまる記述しました. 本丸のbindの記述ですが,以下のようになります.

Kodein.Module {
  bind<Interceptor>() with instance(HttpLoggingInterceptor())
}

以上で,Interceprorインスタンスのinjectが可能になります. bind<T>で型を指定する場合には,その型で参照することができるようになります. 上記のように,生成メソッドと期待する型が違う場合に便利です. もし,withより右側で生成されるインスタンスの型をそのままinjectしたい場合は,もっと簡単に書くことができます.

Kodein.Module {
  bind() from instance(HttpLoggingInterceptor()) // HttpLoggingInterceptorとして提供される
}

Singleton binding

もし,提供したいインスタンスをSingletonに保ちたい場合には,

Kodein.Module {
  bind<OkHttpClient>() with singleton { OkHttpClient.Builder().addNetworkInterceptor(HttpLogginInterceptor()).build()}
}

と書けばSingletonにできます.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment