Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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()
}
yumemi
みんなが知ってるあのサービス、実はゆめみが作ってます。スマホアプリ/Webサービスの企画・UX/UI設計、開発運用。Swift, Kotlin, PHP, Vue.js, React.js, Node.js, AWS等エンジニア・クリエイターの会社です。Twitterで情報配信中https://twitter.com/yumemiinc
http://www.yumemi.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away