Dagger-Hiltとは？

![スクリーンショット 2024-01-23 23.32.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639815/26a88468-10a4-6559-9462-7a592a5fb035.png)


#  *Dagger-Hilt*
HiltはGoogleが提供するDIライブラリで、Daggerを基に作られています。Dagger2と比べて理解しやすく、使いやすいです。また、Googleが積極的にサポートしており、Composeにも適しています。まだアルファやベータ版が出ている段階ですが、注目して学ぶ価値があります。

### 依存性注入に必要な要素

* <span style="color:#FA5882">Application class
</span>  : Hiltを使用するすべてのアプリは ```@HiltAndroidApp``` アノテーションを ```Application Class```に必ず追加し、依存性注入の開始点を指定する必要があります。
Hiltは ```Application``` ライフサイクルに従い、コンパイル段階で ```DI```に必要なコンポーネントを初期化します。
<br/>

  ```kotlin
  @HiltAndroidApp
  class GeunTaeHobbyApplication : Application()
  ``` 
  <br/>
  クラスを作成し、AndroidManifest.xmlに名前を設定します。
  
  ```kotlin
  <application
        android:name=".GeunTaeHobbyApplication"
        ...
  </application>
  ``` 
  <br/>
  
* <span style="color:#FA5882">AndroidEntryPoint</span>    :  
依存性注入が必要なActivityには ```@AndroidEntryPoint``` アノテーションを宣言して、Hilt注入に必要なコンポーネントを作成し、注入の開始点を知らせます。

```kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
...
}
  ``` 
<br/>

####  Dagger-Hiltで使用される概念

* injection </br>  
* Modules </br>
* Binds </br>
* Provides </br>
* Qualifiers </br>
* Components </br>
* ViewModel

# Inject Constructor
- クラスのコンストラクタで ```@Inject``` アノテーションを使用して依存性を作成する方法であり、コンストラクタ ```constructor()```に ```@Inject``` アノテーションで依存性インスタンスを作成し、コンストラクタのパラメータで依存性を注入することもできます。これにより、どのクラスオブジェクトが必要かHiltも開発者も知ることができます。

```kotlin
class HomeAssetDataSource @Inject constructor(
    private val assetLoader: AssetLoader
) : HomeDataSource {
  ...
    }
}
``` 


# Field Injection
- オブジェクトがHiltによって注入を受けることができるクラスであることを示すために付けられます。

```kotlin
// このクラスを作成しなくてもオブジェクトを注入して使用できる
@Inject lateinit var homeAssetDataSource: HomeAssetDataSource
``` 

# Method Injection

-  パラメータに注入して使用する方法で、 <span style="color:#FA5882">Dagger2と同様、注入で最も多く使用されるのはコンストラクタ注入とフィールド注入です。 </span>


```kotlin
// パラメータに注入して使用する
  @Inject
  fun directToDatabase(databaseService: DatabaseService) {
  atabaseService.log("Method Injection")
}
``` 


# Binds

-  Binds方式は ```Provide```と異なり、 ```interface```型のオブジェクトにHiltに知らせるためのもので、外部ライブラリでは使用できず、抽象的に使用します。

```kotlin
 //interface型のオブジェクトをどのように作るかHiltに知らせるためのもの
 @Binds
 abstract fun bindCartItemDataSource(
 dataSource: CartItemLocalDataSource
 ): CartItemDataSource
``` 


# Modules
#### 1.ModuleとInstallIn

```@Module```と ```@InstallIn``` の宣言は、以下のような形で宣言され、 ```@InstallIn``` 内に含まれるHiltコンポーネントと詳細については以下で説明します。

- Dagger2とは異なり、Hiltモジュールは ```@Module```をして、さらに ```@InstallIn(component)``` アノテーションを指定して、どのコンポーネントにinstallするかを必ず決定する必要があります。

そして ```@InstallIn(component)```はライフサイクルを内部的に自動的に管理するため、環境を提供します。


#### 2. Scope
- 依存性注入で毎回オブジェクトを新しく作成するのではなく、該当する ```Scope``` 内で使用できるようにするものです。

# Provides
- Bindsではできないが、Providesは外部からモジュールを注入することが可能です。
  ```Room DB```, ```Retrofit```, ```Gson```, ```Application```, ```Context``` などが可能です。引数にapplicationを入れるとHiltが自動的に挿入します。

```kotlin
@InstallIn(SingletonComponent::class)
@Module
object AssetModule {

    @Provides
    @Singleton
    fun providesAssetLoader(@ApplicationContext appContext: Context): AssetLoader =
        AssetLoader(appContext)

    @Provides
    @Singleton
    fun provideTodoAssetDataSource(assetLoader: AssetLoader): HomeAssetDataSource {
        return HomeAssetDataSource(assetLoader)
    }

    @Provides
    @Singleton
    fun provideTodoAssetRepository(assetDataSource: HomeAssetDataSource): HomeRepository {
        return HomeRepository(assetDataSource)
    }

}
``` 


# Qualifiers

- Dagger2では ```@Named("Identifier")``` アノテーションを使用したのと似ており、同じタイプのオブジェクトを区別するためのものです。


```kotlin
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class CallInterceptor
``` 
<br/>

```kotlin
 @ResponseInterceptor
 @Provides
 fun provideResponseNetworkService(): NetworkService {
     return NetworkService.Builder()
         .host("google.com")
         .protocol("HTTPS")
         .interceptor(ResponseInterceptorImpl())
          .build()
  }
``` 
<br/>

```kotlin
 @CallInterceptor
 @ResponseInterceptor
 @Inject lateinit var networkService: NetworkService
``` 
<br/>


# ViewModel

- ```@HiltViewModel``` アノテーションと ```@Inject``` アノテーションを使用すると、簡単に```ViewModel``` の依存性注入を活性化できます。
```@HiltViewModel```に依存性を注入すると、以前使用していた ```ViewModel```のファクトリーパターンを削除しても問題ありません。サポートがあるためです。

そして

昔のバージョンには ```@HiltViewModel``` ではない ```Inject```を 入れて使用したが現在はバージョンが上がるにつれて削除されました。

<br/>

```kotlin
@HiltViewModel
class CartViewModel @Inject constructor(
    private val cartRepository: CartRepository
) : ViewModel() {

   ...
}
``` 
<br/>



参考

https://0391kjy.tistory.com/55
https://developer88.tistory.com/349
https://salmonpack.tistory.com/41?category=1118477
https://developer.android.com/training/dependency-injection/hilt-android?hl=ko