
みなさまこんにちは〜!
メモリアインクのすだです。
今回は、Hiltというライブラリを使ったDI(依存性注入)について、詳しく解説していきます!
この記事を読んでわかること…
・Hiltとは?
・Hiltを使ったDI(依存性注入)のやり方
DI(依存性注入)の基本については、以下の記事で解説しておりますので、ぜひ一緒にご覧ください。
とは?基本的な考え方と必要性についてわかりやすく解説!-300x158.png)
とは?基本的な考え方と必要性についてわかりやすく解説!-300x158.png)
環境
- Kotlin (ver 1.9.0)
- Android Studio (Giraffe | 2022.3.1 Patch 3)
Hiltとは?
Hiltは、Googleが提供するDIライブラリです。
https://developer.android.com/training/dependency-injection/hilt-android?hl=ja
Androidアプリ開発に最適化されており、以下の特徴があります:
@Inject
などのアノテーションで簡単にDIができる- ActivityやViewModel、Fragmentに自動的に依存関係を注入可能
- テスト支援も充実
- Jetpackライブラリと高い互換性
手動DIでは依存関係の管理がどんどん大変になりますが、
Hiltを使えばその多くを自動化できるため、よりスムーズに開発できます。
Hiltの導入方法(セットアップ)
Hiltライブラリを使用するために、build.gradleに以下の設定を行います。
プロジェクトレベルのbuild.gradle▼
buildscript {
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.48"
}
}
モジュールレベルのbuild.gradle▼
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies {
implementation "com.google.dagger:hilt-android:2.48"
kapt "com.google.dagger:hilt-compiler:2.48"
}
HiltのバージョンはKotlinのバージョンに依存するので、導入時はバージョンをよく確認してください。
そして、Applicationクラスに以下のアノテーションを付与してください。▼
@HiltAndroidApp
class MyApplication : Application()
Hiltを使ったDIのやり方
たとえば、以下の「手動でDIを行った処理」があるとします。
手動DI ▼
// 依存クラス
class ApiClient {
fun fetchUser(): String = "Taro"
}
// 依存を使うクラス
class UserRepository(private val apiClient: ApiClient) {
fun getUser(): String = apiClient.fetchUser()
}
// 呼び出し処理
class MainActivity : AppCompatActivity() {
lateinit var userRepository: UserRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val apiClient = ApiClient()
val userRepository = UserRepository(apiClient)
println(userRepository.getUser()) // → Taro
}
}
これを、Hiltを使うように変更してみます。▼
1. ApiClient
に @Inject
を付ける
class ApiClient @Inject constructor() {
fun fetchUser(): String = "Taro"
}
依存クラスのコンストラクタに @Inject
(= 依存を注入できるマーク)を付けることで、Hiltがこのクラスのインスタンスを自動で生成できるようになります。
Kotlinでは通常、constructor()
の記述は省略できますが、Hiltでは @Inject constructor()
という形で明示的に書く必要があります。
これにより、「このコンストラクタを使って ApiClient
を作成してください」とHiltに指示できます。
2. UserRepository
にも @Inject
を付ける
class UserRepository @Inject constructor(private val apiClient: ApiClient) {
fun getUser(): String = apiClient.fetchUser()
}
UserRepository
も ApiClient
に依存しているため、同様に @Inject constructor(...)
を付けます。
これにより、Hiltが ApiClient
を先に生成し、それを使って UserRepository
を自動で組み立ててくれます。
つまりこの記述は、「このコンストラクタを使って UserRepository
を作ってください」とHiltに伝えていることになります。
3. MainActivity
に @AndroidEntryPoint
を付ける
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var userRepository: UserRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println(userRepository.getUser()) // ← Hiltが自動で注入
}
}
@AndroidEntryPoint
は、「このクラスでHiltによる依存注入を使いたい」と宣言するアノテーションです。
このマークをクラス名の上に付けることで、Hiltが MainActivity
をDI(依存性注入)の対象として認識します。
さらに、注入したいプロパティには @Inject
を付けます。
これにより、Hiltが UserRepository
のインスタンスを自動で生成して userRepository
に依存を注入してくれます。
依存関係の流れを図解すると:
MainActivity
↓ @Inject
UserRepository
↓ @Inject constructor(apiClient)
ApiClient
↑ @Inject constructor ← Hiltがここも作る
このように、MainActivity は UserRepository を使い、
UserRepository は ApiClient を使います。
このようにHiltは依存をたどって必要なものを全部作ってくれるのです。
Hiltの使い所
「Hiltの使い所」は大きく3つのパターンに分類できます。
constructor や プロパティ
これは先ほどご紹介した例です。@Inject constructor(...)
/ @Inject lateinit var ...
といった形でコンストラクタやプロパティにInjectアノテーションをつけてあげることによるDI。Hiltがインスタンスを作ったり、注入するために使う基本と言えます。
class ApiClient @Inject constructor() { ... }
class MainActivity : AppCompatActivity() {
@Inject lateinit var apiClient: ApiClient
}
ViewModel クラス
Hiltは、ViewModelを含む複数のJetpack コンポーネントと公式に統合されているため相性がとても良いです。
ViewModelに依存を注入するには、@HiltViewModel
という専用のアノテーションが必要です。
@HiltViewModel
class UserViewModel @Inject constructor(
private val repository: UserRepository
) : ViewModel() {
fun getUserName(): String = repository.fetchUser()
}
より詳しい実装に関しては以下の記事でご紹介しておりますのでぜひご覧ください。
|FactoryとHiltを丁寧に比較解説-300x158.png)
|FactoryとHiltを丁寧に比較解説-300x158.png)
object
Hiltで外部ライブラリや手動インスタンスを注入したいとき、@Module
+ @Provides
を使ってDIできます。
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.build()
}
}
より詳しい実装に関しては以下の記事でご紹介しておりますのでぜひご覧ください。


まとめ
おつかれさまでした。いかがでしたでしょうか!
はじめてHiltなどのDIライブラリを導入する方は少し違和感を感じるかもしれませんが、
慣れてくると使いやすさを感じるかと思います!



技術者としてのキャリアパスを次のレベルへと進めたい皆様、
<未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】>
自分の市場価値をさらに向上させてみませんか?
それではまた次回の記事でお会いしましょう!
コメント