Koinを使ってActivityやFragmentを注入する方法です。
前提とするシチュエーション
FluxのActionCreatorのようなクラスにおいて、
LifecycleOwnerとしてActivityやFragmentを注入しておき、
必要に応じてビジネスロジックを中断する事を想定しています。
実装
Activityを注入するクラス
あくまで例ですが、LifecycleOwnerとしてActivityを注入したいケースは多々あるかと思います。
class ActionCreator(lifecycleOwner: LifecycleOwner) : LifecycleObserver {
init {
lifecycleOwner.lifecycle.addObserver(this)
}
}
Koin Module
Koin moduleのfactory
メソッドには引数ParameterList
があります。Koin内で定義されたクラスです。動的に渡すパラメータを格納するList型のラッパーです。
このParameterList
からLifecycleOwnerを取り出すことにします。
module {
factory {
ActionCreator(it.get<LifecycleOwner>() as LifecycleOwner)
}
}
また、ParameterList
は分解宣言に対応しているため、以下のような利用も可能です。
module {
factory { (lifecycleOwner: LifecycleOwner) -> ActionCreator(lifecycleOwner) }
}
Activity
ActivityではActionCreatorをinjectしますが、このとき自分(LifecycleOwner)を含んだParameterList
を渡します。
class MainActivity : AppCompatActivity() {
val actionCreator: ActionCreator by inject { parametersOf(this) }
}
拡張
冗長な記述を拡張関数でコンパクトにしてみます。
// for Activity
fun <R> R.defaultParameterDefinition(): ParameterDefinition
where R: ComponentCallbacks, R: ComponentActivity {
return { parametersOf(this) }
}
inline fun <reified T : Any, R> R.injectMySelf(name: String = "", scope: Scope? = null)
where R: ComponentCallbacks, R: ComponentActivity
= lazy { get<T>(name, scope, defaultParameterDefinition()) }
// for Fragment
fun <R> R.defaultParameterDefinition(): ParameterDefinition
where R: ComponentCallbacks, R: LifecycleOwner {
return { parametersOf(this) }
}
inline fun <reified T : Any, R> R.injectMySelf(name: String = "", scope: Scope? = null)
where R: ComponentCallbacks, R: LifecycleOwner
= lazy { get<T>(name, scope, defaultParameterDefinition()) }
injectMySelf
は自分自身をinjectするプロパティデリゲートを生成します。
ActivityやFragmentでは以下のように利用できるはずです。
class MainActivity : AppCompatActivity() {
val actionCreator: ActionCreator by injectMySelf()
}