본문 바로가기
Android/Hilt

[Android/Hilt] @Inject와 @Module, @Provides 이해하기

by quessr 2025. 3. 7.

 

Hilt는 안드로이드에서 의존성 주입(DI, Dependency Injection)을 쉽게 구현할 수 있도록 도와주는 라이브러리입니다.

Hilt를 사용하면 의존성 관리를 더욱 효율적으로 할 수 있으며, 코드가 간결해집니다.

특히 @Inject@Module, @Provides는 Hilt에서 가장 중요한 개념 중 하나입니다.

이번 글에서는 이 두 개념을 정리해보겠습니다.


@Inject: 직접 만든 클래스의 의존성 주입

@Inject직접 만든 클래스의 의존성을 Hilt가 자동으로 관리할 수 있도록 도와줍니다.

@Inject constructor를 사용한 생성자 주입

class ExampleRepository @Inject constructor() {
    fun getData(): String = "Hello from Repository"
}

 

위처럼 @Inject를 클래스의 생성자에 붙이면, Hilt가 ExampleRepository를 의존성 그래프에 자동 등록해줍니다.

이렇게 하면 다른 클래스에서 ExampleRepository를 쉽게 주입받을 수 있습니다.

@Inject를 활용한 필드(Field) 주입

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
    
    @Inject
    lateinit var repository: ExampleRepository
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        
        val data = repository.getData()
        Log.d("ExampleActivity", data)
    }
}

 

Hilt는 @Inject를 확인하고 ExampleRepository를 자동으로 주입합니다.

@Inject를 활용한 함수(Function) 주입

class ExampleClass {
    lateinit var repository: ExampleRepository
    
    @Inject
    fun injectRepository(repository: ExampleRepository) {
        this.repository = repository
    }
}

 

Hilt는 injectRepository() 함수가 호출될 때 자동으로 ExampleRepository 객체를 주입합니다.

@Inject를 사용하면 좋은 경우

  • 직접 만든 클래스라서 Hilt가 생성할 수 있는 경우
  • 별도의 설정 없이 간단하게 의존성을 주입하고 싶을 때

@Module@Provides: 외부 라이브러리의 의존성 주입

외부 라이브러리(Retrofit, Room, SharedPreferences 등)는 @Inject를 직접 붙일 수 없습니다.

이런 경우 @Module@Provides를 사용하여 Hilt에 의존성을 제공해야 합니다.

@Module, @InstallIn@Provides를 이용한 의존성 제공

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    
    @Provides
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .build()
    }
}

Hilt 동작 방식

  1. @Module을 사용하여 의존성을 제공하는 클래스를 정의합니다.
  2. @InstallIn(SingletonComponent::class)를 사용해 Hilt가 어느 범위에서 이 모듈을 사용할지 설정합니다.
  3. @Provides를 사용하여 의존성을 제공할 함수를 선언합니다.
  4. provideRetrofit()의 반환값(Retrofit)을 Hilt의 의존성 그래프에 등록합니다.

이제 Retrofit이 필요한 곳에서 @Inject를 사용하면 자동으로 주입됩니다.

class ApiService @Inject constructor(private val retrofit: Retrofit) {
    fun fetchData() {
        // retrofit 사용 가능
    }
}

 

 

Hilt는 @Inject를 확인하고, @Module에서 제공한 Retrofit 객체를 찾아서 ApiService에 자동 주입합니다.

@Module@Provides를 사용해야 하는 경우

  • Retrofit, Room, SharedPreferences 같은 외부 라이브러리를 주입할 때
  • 생성자에서 직접 @Inject를 사용할 수 없는 경우 (예: Builder 패턴이 필요한 경우)

인터페이스의 구현체를 제공해야 할 경우@Binds를 활용하는 것이 더 적절합니다. @Provides는 구체적인 객체를 반환해야 하지만, @Binds는 인터페이스의 구현체를 지정할 때 사용됩니다.


@Inject vs @Module@Provides 정리

구분 사용 방법 사용해야 하는 경우
@Inject @Inject constructor() 직접 만든 클래스를 자동으로 주입할 때
@Inject 필드 주입 (@Inject lateinit var) 액티비티, 프래그먼트에서 주입할 때
@Inject 함수 주입 (@Inject fun injectXXX()) 특정 함수에서 주입이 필요할 때
@Module@Provides @Module@Provides로 제공 외부 라이브러리 객체를 주입할 때
@Module + @Binds @Binds를 사용해 구현체 제공 인터페이스의 구현체를 주입할 때

결론

  • 직접 만든 클래스는 @Inject를 사용하면 자동으로 주입됩니다.
  • 외부 라이브러리는 @Module@Provides를 사용하여 주입해야 합니다.
  • @InstallIn을 사용해 Hilt가 어느 범위에서 이 모듈을 사용할지 설정해야 합니다.
  • 인터페이스의 구현체를 주입할 때는 @Binds를 사용하는 것이 적절합니다.
  • Hilt는 반환 타입을 기준으로 의존성을 찾아서 자동으로 주입해 줍니다.
반응형