Koinにはコンストラクタ注入もあることを知った
コンストラクタ注入とは、コンストラクタを通じて依存関係を直接渡す形で注入すること
コンストラクタ注入の例
1. 依存関係となるクラス
まず、MyRepositoryとMyServiceという2つのクラスを定義します。MyServiceはMyRepositoryに依存している
class MyRepository { fun getData(): String = "Hello from MyRepository" } class MyService(private val repository: MyRepository) { fun sayHello(): String { return repository.getData() } }
ここで、MyServiceはコンストラクタを通じてMyRepositoryを受け取っている
このようにコンストラクタで依存関係を指定することで、依存関係の注入を自然な形で表現できる
2. Koinモジュールで依存関係を定義
次に、Koinのmoduleを使って依存関係を定義する
singleを使ってシングルトンとしてインスタンスを提供する
val appModule = module { single { MyRepository() } single { MyService(get()) } // コンストラクタに依存関係を注入 }
ここでMyService(get())のget()は、KoinがMyRepositoryのインスタンスを提供してくれることを意味する
3. Koinの開始
アプリケーションのエントリーポイントでKoinを開始する
class MyApplication : Application() { override fun onCreate() { super.onCreate() startKoin { androidContext(this@MyApplication) modules(appModule) } } }
4. ViewModelや他のクラスでの利用
次に、Koinを使ってMyServiceを注入
コンストラクタでの注入を利用しているので、Koinは自動的に依存関係を解決する
class MyViewModel(private val myService: MyService) : ViewModel() { fun displayMessage(): String { return myService.sayHello() } }
🎯 by inject() とコンストラクタ注入の違い
by inject()
by inject()はKoinが提供するプロパティデリゲートを利用したフィールドインジェクション
これは、クラスの中で後から依存関係を注入したいときに使う
class MyViewModel : ViewModel() { private val myService: MyService by inject() // by inject()で依存関係を遅延注入 }
特徴:
使い所:
コンストラクタ注入
依存するオブジェクトを明示的にコンストラクタで受け取るため、クラスの設計がクリーンになる
class MyViewModel(private val myService: MyService) : ViewModel() { fun displayMessage(): String { return myService.sayHello() } }
特徴:
使い所:
- テストやモックが必要なクラスや、依存関係が多いクラスに適している
- 依存関係の注入をクラスの設計に統合したい場合、コンストラクタで注入することでクラスの責務をより明確にできる
使い分け
by inject()を使うべき場合
- 遅延初期化が必要な場合、またはインスタンスが使われない限りオブジェクトを生成したくない場合