경험의 기록

2021.06.03 - [Android/AAC, MVVM] - [Android] Dagger Hilt 사용하여 의존성 주입(DI) 하기

 

[Android] Dagger Hilt 사용하여 의존성 주입(DI) 하기

0️⃣ 의존성 주입(DI) 이란? 먼저, 의존성이란 A 클래스가 자체적인 B 클래스를 구성하는 것을 말한다. 구글의 예시를 통해 알아보자. 그림과 같이 Car라는 클래스가 Engine 라는 클래스를 가져다 쓰

hanyeop.tistory.com

Dagger Hilt를 다시 학습하는 도중 헷갈리는 부분이 있어 정리해보려고 한다.

 


 

String, Int 등 일반적인 타입을 주입

Dagger Hilt 사용 시 String, Int 등 일반적인 타입을 주입하고 사용할 때에는

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Singleton
    @Provides
    @Named("String1")
    fun provideTestString() = "테스트 문자가 주입되었습니다."

    @Singleton
    @Provides
    @Named("String2")
    fun provideTestString2(
        @ApplicationContext context : Context,
        @Named("String1") string1 : String
    ) = "${context.getString(R.string.string_string2)} 그리고, $string1"
}

위와 같이 원하는 컴포넌트에 모듈을 설치하여 @Provides 를 통해 hilt가 어떤 것을 주입해야 하는지를 알려줘야 한다.

또한 같은 타입이 2개 이상일 경우 @Named 어노테이션으로 이름을 별도로 지정해준다.

@Singleton 은 이 객체를 싱글톤으로 생성해준다.

 

그럼 위처럼 @Inject, @Named 를 통해 알맞은 객체를 주입받을 수 있다.

 

 

Class 의존성 주입

class Data {
    var a = 10

    fun set(){
        Log.d("test5", "set: $a")
        a = 20
    }

    fun get(){
        Log.d("test5", "get: $a")
    }
}

 

위와 같은 클래스가 있을 때

 

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    fun provideClass() = Data()
}

String을 주입할 때처럼 @Provides 를 사용하여 hilt가 어떤 것을 주입해야 하는지를 지정할 수 있다.

하지만 String과 다르게 위 클래스는 사용자가 직접 정의한 클래스이므로 여러 개 존재하지 않는다.

 

class Data @Inject constructor() {
    var a = 10

    fun set(){
        Log.d("test5", "set: $a")
        a = 20
    }

    fun get(){
        Log.d("test5", "get: $a")
    }
}

따라서 @Inject 을 통해 생성자 파라미터로 어떠한 것이 필요한지 명시해주면 (위 경우는 생성자 파라미터 X)

따로 @Provides 코드를 작성하지 않아도

 

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var data : Data
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}

hilt는 Data 클래스를 알아서 주입해준다.

따라서 위와 같이 사용할 액티비티에서 @Inject 하여 사용할 수 있다.

 

따라서 처음에 살펴본 @Provides 로 전달하는 방법은 @Singleton  사용하여 싱글톤으로 클래스 객체를 생성할 때 등 클래스를 기본적으로 생성하지 않을 때 사용할 수 있다.

 

 

Class 생성자 파라미터 주입

class Data @Inject constructor(
    @Named("String1") private val str: String
) {
    var a = 10

    init {
        Log.d("test5", "string: $str")
    }

    fun set(){
        Log.d("test5", "set: $a")
        a = 20
    }

    fun get(){
        Log.d("test5", "get: $a")
    }
}

위와 같이 필요한 생성자 파라미터를 정의해주면 Hilt가 주입해준다.

 

 

❓ Hilt가 자동으로 주입해주는 부분에 직접 파라미터를 넣어도 될까?

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var data : Data
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        data.set()

        val data2 = Data("test")
        data2.get()
    }
}

잘 되는 것을 확인할 수 있다.

 

 

 


Dagger Hilt는 잘 사용하면 굉장히 편한 라이브러리인 것 같다.

그런데 사용 시 오류 잡기가 어려워 완벽히 사용하기 쉽지 않은 것 같다...

 

공부하며 작성한 내용이라 틀린 부분이 있을 수 있습니다.

틀린 부분이 있다면 말씀해주세요!

 

https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/DaggerHiltEx

 

GitHub - HanYeop/AndroidStudio-Practice2: (2021.05.20~) 안드로이드 학습 내용 저장소

(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.

github.com

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading