본문 바로가기

[Android]/App UI 따라 만들기

[배달의 민족] 따라만들기 10-3편 (Dagger-Hilt)

안녕하세요! 허접 샴푸입니다.

 

오늘은 Dagger-Hilt 3편입니다!

 

지난 포스트 (2편)에서 이어 나가겠습니다.

 

가장 먼저 기본적인 세팅을 끝났으니, 이제는 무엇을 모듈로 만들지를 정해야 합니다.

가장 먼저 저희는 Repository를 모듈로 만들고자 합니다.

 

1) RepositoryModule 생성

먼저 "di"라는 package를 생성 후 RepositoryModule 코틀린 파일을 만듭니다. (Object)

 

2) Dagger-Hilt 속성 작성

위와 같이 작성을 해줍니다.

Module은 단순히 Dagger 그래프를 위해 @Module이라고 Annotation 작업을 한 클래스입니다. 모듈 안에서 의존성들을 @Provides Annotation과 함께 정의할 수 있습니다.

 

Repository Pattern에서 Repository는 뷰, 뷰 모델과 별개로 존재해야 하며, 어디서든 접근이 가능해야 하므로 Singleton 컴포넌트로 작성을 합니다. 그리하여 Repository 모듈은 InstallIn(SingletonComponent::class)를 통해 싱글턴 모듈임을 나타내도록 합니다.

더불어 현재까지 저희가 완전한 코드를 작성하지 않았기에, HomeRepository와 EatWhatRepository만 존재하며, 일단 만든 두 repository를 @Singleton, @Provides annotation을 통해 작성을 합니다. 참고로 모듈에 SingletonComponent라고 작성을 해주었지만, Dagger-Hilt 공식 문서에서 나와 있듯이, @Singleton annotation을 필수로 작성을 하라고 되어 있습니다(싱글턴으로 사용하고자 하면).

 

즉 Dagger Graph에서는 HomeRepository와 EatWhatRepository가 추가되어, 뷰 모델에서 해당 싱글턴 객체를 주입하고자 하면 새로운 인스턴스 생성이 아닌 Dagger가 알아서 해당 객체를 주입시켜 줍니다.

 

참고로 Repository는 왜 싱글턴 객체여야 하는가? Repository는 네트워크 작업 혹은 데이터베이스 작업을 위해 만들어진 뷰와 뷰 모델과는 별개의 공간입니다. 만약 싱글턴이 아닌 단순 클래스라고 가정하면, 매번 네트워크 작업 혹은 데이터베이스 작업이 일어날 시 새로운 클래스 객체를 생성한다는 것은 매우 비효율적입니다. 만약 클래스 생성이 오래 걸린다고 가정하면, 네트워크 작업 및 데이터베이스 작업을 하기 위해 클래스 객체를 생성하는 것은 네트워크 처리, 데이터베이스 처리 시간에 더해져 매우 오래 걸릴 것입니다. 그래서 싱글턴 객체로 선언을 하여 항상 어디서든 준비되어 있도록 합니다.

 

3) MainActivity에 @AndroidEntryPoint annotation 작성

앞으로 Dagger Hilt를 사용하기 위해서는 @AndroidEntryPoint annotation을 위와 같이 작성해야 합니다(사용하고자 하는 곳). 이 앱에서 Activity와 Fragment 등으로 이루어져 있으며, 해당 액티비티와 프레그먼트에서는 뷰 모델을 사용할 것이며, 각각의 뷰 모델은 repository를 참조해야 하므로 Activity와 Fragment에 모두 @AndroidEntryPoint를 작성해야 합니다. 물론 BaseActivity나 BaseFragment를 만들어서 쉽게 처리할 수 있으나, 이는 추후 Refactoring 과정에서 알아봅시다!

 

4) 나머지 Fragment에 @AndroidEntryPoint annotation 작성

-> HomeFragment, EatWhatFragment, FavoriteFragment, OrderFragment

 

5) HomeViewModel과 EatWhatViewModel @HiltViewModel annotation 작성

[1] HomeViewModel

[2] EatWhatViewModel

위와 같이 ViewModel 클래스에 @HiltViewModel annotation을 작성합니다. 그리고 constructor 위에 @Inject 마킹을 통해 의존성을 주입시킵니다. 더불어 @HiltViewModel annotation을 통해서, Dagger Hilt는 HiltViewModelFactory를 생성하여, 생성자 파라미터를 자동으로 주입시켜 줍니다. 기존에 Activity에서 viewModel을 생성할 때 어떠한 변수나 객체를 생성자로 넘기려고 하면 viewModelFactory클래스를 별도로 만들어줘야 하는 번거로움이 있었습니다. Dagger Hilt를 사용하게 되면, Dagger Hilt가 알아서 모두 처리해주기 때문에 저희가 따로 뷰모델 팩토리를 생성한다는 등의 번거로운 작업을 피할 수가 있습니다.

 

RepositoryModule에서 Repository들을 @Provides 통해 제공하기 때문에 ViewModel에서는 단순히 constructor에 @Inject annotation과 함께 작성만 하면 해당 repository 객체를 자유자재로 접근 및 사용할 수 있게 됩니다. 매우 편리하죠?

 

지금은 저희가 constructor 파라미터, 즉 레퍼지토리 싱글턴 객체를 생성할 때 필요한 파라미터가 없기 때문에, 굳이 저렇게 해야 할 필요가 있을까 싶겠지만, 추후 코드를 추가하다 보면 왜 필요한지를 알게 될 것입니다.

 

[Github 현재까지 완성된 코드]

github.com/DJDrama/BaeminPractice/tree/Dagger-Hilt-Setup3

 

DJDrama/BaeminPractice

Contribute to DJDrama/BaeminPractice development by creating an account on GitHub.

github.com

 

다음 편에서는 TabLayout, ViewPager2를 이용한 "주문 내역" 화면을 만들도록 하겠습니다.

자주 글을 올리지 못해 죄송합니다. 

 

공감 하트 눌러주시면 감사하겠습니다.