用 Java 進行 Android 開發的話,依賴注入這一塊通常使用 Dagger ,轉用 Kotlin 以後有更多的選擇,Kodein 是個不錯的庫, 4.0 5.0 都使用過了,相對於 Dagger 有不少好處。android
KodeinAware
並綁定依賴class MyApp : Application(), KodeinAware {
override val kodein = Kodein.lazy {
/* bindings */
}
}
複製代碼
closestKodein
方法獲取class MyApp : Application(), KodeinAware {
//實例化 Application 級的 kodein 經過 DSL 綁定 module
override val kodein = Kodein.lazy {
//導入預設的 android 組件
import(androidModule(this@MainApplication))
//綁定或者導入自定義依賴
}
}
複製代碼
Kodein
class MyApp : Application(), KodeinAware {
//實例化 Application 級的 kodein 經過 DSL 綁定 module
override val kodein = Kodein.lazy {
//導入預設的 android 組件
import(androidModule(this@MainApplication))
//綁定或者導入自定義依賴
}
}
複製代碼
Kodein
而後經過 Kodein
加載依賴class MyActivity : Activity(), KodeinAware {
override val kodein by closestKodein()
val ds: DataSource by instance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ds.connect()
/* ... */
}
}
複製代碼
一樣能夠避免依賴死循環(除非加載依賴的方式只有 instance)bash
class MyActivity : Activity(), KodeinAware {
override val kodein by closestKodein()
override val kodeinTrigger = KodeinTrigger()
val ds: DataSource by instance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
kodeinTrigger.trigger()
/* ... */
}
}
複製代碼
class MyController(androidContext: Context) : KodeinAware {
override val kodein by androidContext.closestKodein()
override val kodeinContext = kcontext(androidContext)
val inflater: LayoutInflater by instance()
}
複製代碼
Kodein
繼承自 Application 級class MyActivity : Activity(), KodeinAware {
private val _parentKodein by closestKodein()
override val kodein: Kodein = Kodein {
extend(_parentKodein)
/* activity specific bindings */
}
}
複製代碼
class MyActivity : Activity(), KodeinAware {
private val _parentKodein by closestKodein()
override val kodein: Kodein by retainedKodein {
extend(_parentKodein)
/* activity specific bindings */
}
}
複製代碼
//每一個 Activity 一個單例
val kodein = Kodein {
bind<Controller>() with scoped(androidScope<Activity>()).singleton { ControllerImpl(context) }
}
複製代碼
val kodein = Kodein {
bind<Controller>() with scoped(activityRetainedScope).singleton { ControllerImpl() }
}
複製代碼
() -> T
() → T
() -> T
(A) -> T
(A) -> T
val kodein = Kodein {
bind<Die>() with ...
bind<Die>(tag = "DnD10") with ...
bind<Die>(tag = "DnD20") with ...
}
複製代碼
OutOfMemoryException
以前 JVM 執行 GCval kodein = Kodein {
bind<Map>() with refSingleton(ref = softReference) { WorldMap() }
bind<Client>() with refSingleton(ref = weakReference) { id -> clientFromDB(id) }
}
複製代碼
class Die(private val random: Random, private val sides: Int) {
/*...*/
}
val kodein = Kodein {
bind<Die>() with singleton { Die(instance(), instance(tag = "max")) }
bind<Random>() with provider { SecureRandom() }
constant(tag "max") with 5
}
複製代碼