Edited at

Koinを使ってActivityやFragmentをInjectionする

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()
}