안드로이드에서의 의존성 주입

이윤설·2025년 2월 27일
0

안드로이드 연구소

목록 보기
21/33

1. 의존성 주입(Dependency Injection)과 의존성 제어

의존성이란?

의존성(Dependency)이란 클래스가 다른 클래스 또는 객체에 의존하는 관계를 의미한다.

예를 들어, UserRepository 클래스가 ApiService 객체를 필요로 한다면, UserRepositoryApiService에 의존성을 갖는다고 볼 수 있다.

class UserRepository {
    private val apiService = ApiService()
}

위 코드는 UserRepositoryApiService를 직접 생성(new)하고 있어 강한 결합이 발생한다.
만약 ApiService가 없어지거나 파라미터 변경이 생기면 UserRepsitory 까지 영향이 전달된다.

의존성 주입이란?

의존성 주입(DI)은 객체를 직접 생성하는 것이 아니라 외부에서 주입받는 방식을 의미한다.
즉, UserRepositoryApiService를 직접 생성하지 않고, 외부에서 제공하도록 설계하는 것이다.

class UserRepository(private val apiService: ApiService) {
    fun getUser() = apiService.fetchUser()
}

이렇게 하면 UserRepositoryApiService의 생성 방식에 대해 알 필요가 없고, 테스트할 때 Mock 객체를 쉽게 주입할 수 있어 유연성이 높아진다.


이런 식으로 의존성 주입을 설정하면, 제어의 역전이 이루어진다.
제어를 나타내는 화살표의 방향이 역전이 된 것을 확인할 수 있다.
이는 개발자가 직접 의존성을 제어하던 것을, 어떠한 매개체에게 제어권을 일임하여 더이상 제어의 주체가 개발자가 아니게 되는 것이라고 보면 된다.


2. 안드로이드에서 Hilt를 사용한 의존성 주입

Hilt란?

Hilt는 Dagger 기반의 안드로이드 DI 라이브러리로, 구글이 공식 지원하며 의존성 관리를 단순화할 수 있도록 도와준다.

기존 Dagger보다 설정이 간단하며, @HiltAndroidApp, @Inject, @Module, @Provides, @Binds 등의 어노테이션을 활용해 의존성을 쉽게 주입할 수 있다.

Hilt 적용 방법

1. 프로젝트에 Hilt 추가

build.gradle (Project)에 아래 설정을 추가한다.

plugins {
    id 'com.google.dagger.hilt.android' version '2.x.x' apply false
}

build.gradle (Module)에 다음 의존성을 추가한다.

plugins {
    id 'com.google.dagger.hilt.android'
}

dependencies {
    implementation "com.google.dagger:hilt-android:2.x.x"
    kapt "com.google.dagger:hilt-android-compiler:2.x.x"
}

2. @HiltAndroidApp 적용

Application 클래스에 @HiltAndroidApp을 추가하면 Hilt가 앱 전체에서 의존성을 관리할 수 있도록 설정된다.

@HiltAndroidApp
class MyApplication : Application()

3. @Inject를 사용한 의존성 주입

Hilt는 생성자 주입(Constructor Injection)을 지원한다.
즉, @Inject를 생성자에 붙이면 Hilt가 자동으로 객체를 주입해 준다.

class UserRepository @Inject constructor(private val apiService: ApiService) {
    fun getUser() = apiService.fetchUser()
}

위처럼 UserRepository@Inject를 추가하면, ApiService 객체를 Hilt가 알아서 주입해 준다.

@Provides vs @Binds 모듈 사용법

Hilt에서는 객체를 제공하는 방법으로 @Provides@Binds를 사용할 수 있다.

1. @Provides 사용 (객체 직접 생성)

@Provides객체를 직접 생성하여 반환할 때 사용한다.

@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
    @Provides
    @Singleton
    fun provideDatabase(
        @ApplicationContext context: Context,
    ): PassionDailyDatabase =
        Room.databaseBuilder(
            context,
            PassionDailyDatabase::class.java,
            "passion_daily.db"
        ).build()

    @Provides
    @Singleton
    fun provideUserDao(database: PassionDailyDatabase): UserDao = database.userDao()
}

언제 사용?

  • 객체를 직접 생성하여 반환할 때
  • Room, Retrofit 같은 외부 라이브러리 사용 시

2. @Binds 사용 (인터페이스와 구현체 연결)

@Binds인터페이스와 구현체 간의 관계를 설정할 때 사용한다.
단, @Binds를 사용하려면 구현체에 @Inject 생성자가 필요하다.

@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
    @Binds
    abstract fun bindLocalFavoriteRepository(
        repository: LocalFavoriteRepositoryImpl
    ): LocalFavoriteRepository
}

언제 사용?

  • 인터페이스를 구현체와 연결할 때
  • 생성자가 @Inject로 자동 주입 가능한 경우

요약


사진 및 참고 출처)
https://www.youtube.com/watch?v=1vdeIL2iCcM

profile
화려한 외면이 아닌 단단한 내면

0개의 댓글

관련 채용 정보