Dagger Hilt를 알아보기 전에 의존성 주입을 하는이유에 대해서 알아보겠습니다.
1.의존성 주입(dependency injection)
-"의존성 주입"은 하나의 객체가 다른 객체에게 의존성을 제공하는 것입니다.
-그러면 의존성이 필요한 이유를 보면서 의존성을 이해해봅시다.
1-1)의존성 주입을 하는이유
-위의 코드처럼 객체를 필드안에서 new 연산자를 생성해서 객체를 생성할 때 문제가
발생합니다.
-만약 Pocket 클래스의 코드가 수정되어서 객체 생성시 입력값이 필요하면 Draemon
클래스도 수정을 해줘야 하는 문제가 발생합니다.
-이것을 객체간의 의존성이 발생한다고 얘기합니다.
1-2)의존성 주입을 통한 객체 생성 방식
-위의 그림의 외부에서 Pocket 객체를 가져와서 주입하면 Pocket클래스의 변경이
생겨도 Draemon클래스는 수정을 하지 않아도 되는 장점이 있습니다.
1-3)의존성 주입의 장점
-코드의 가독성을 높여준다.
-Unit Test가 쉬워진다.
-코드의 재활용성을 높인다.
-객체 간의 의존성을 직접 설정하여 줄이거나 없앨 수 있다.
-객체 간의 결합도를 낮추면서 유연하게 만들 수 있다.
2.의존성 주입 프레임워크
1)Koin
1-1)장점
-별도의 어노테이션을 활용하지 않으므로 상대적으로 가볍습니다.
-Daager에 비해 상대적으로 학습이 쉽습니다.
-ViewModel 주입을 쉽게할 수 있는 별도의 라이브러리 제공
1-2)단점
-Dagger에 비해 런타임시 오버헤드가 있습니다.
-프로젝트의 규모가 커질수록 유지보수하기가 점점 힘들어집니다.
-DSL을 사용해 런타임에서 의존성을 주입함으로 런타임 중에 Eroor가 발생할 수 있다.
2)Dagger2
2-1)장점
-Koin에 비해 대규모 프로젝트의 경우 더욱 유연하게 코드 모듈을 관리할 수 있음.
-컴파일 환경에서 의존성을 주입하기 때문에 빌드가 완료된 시점에선 어느정도
안정성을 보장함.
2-2)단점
-어노테이션, Module, Component간의 역할 관계, Scope등 여러가지 알아야 할 개념이
있어서 상대적으로 학습하는데 시간이 더 걸림
-환경 세팅 작업이 필요함으로 간단한 프로젝트에는 오히려 번거로움 작업이 될 수 있음.
3.Dagger Hilt
-Dagger2를 기반으로 만들어졌으며 기존의 Daagger2의 단점인 환경세팅과 높은
러닝커브를 줄이고 Daager2의 장점들을 모아서 만든 DI 프레임워크
-Hilt를 더 깊게 이해하려면 Dagger2에 대한 공부가 필요합니다.
1)Hilt 사용법
1-1)@HiltAndroidApp
-Hilt를 사용하는 모든 앱은 @HiltAndroidApp으로 주석이 지정된 어플리케이션
클래스를 포함해야 합니다.
-Hilt 관련 컴포넌트, 모듈 등 모든 코드 생성을 시작하는 어노테이션 입니다.
-Hilt를 사용하는 앱은 반드시 @HiltAndroidApp을 가진 Application 클래스를
Manifest App에 포함시켜야합니다.
-HiltAndroidApp은 Application 객체의 수명 주기에 연결된 앱의 최상단 부모 컨포넌트입니다.
-어플리케이션 클래스를 생성하고 @HiltAndroidApp 어노테이션을 붙여야합니다.
-@HIltAndroidApp 어노테이션에 대해서 간단하게 설명하겠습니다.
1-1)@AndroidEntryPoint
-의존성 주입을 받을 엑티비티와 프래그먼트에는 반드시 @AndroidEntryPoint
어노테이션을 등록해야합니다.
1-2)@HiltViewModel
-의존성 주입을 받는 ViewModel에 @HiltViewModel 어노테이션을 등록해야 합니다.
-@Inject Constructor를 통해 Module에 정의한 의존성 객체를 받아올 수 있습니다.
1-3)사용할 Module 작성
-위의 그림처럼 사용할 모듈을 @Module, @InstallIn을 사용해 작성합니다.
-인터페이스를 전달할 때 @Binds를 사용하고 Class객체는 @Provides를 사용해 주입합니다.
2)Module 작성하는 방법
-Module을 작성하는 방법을 이해하려면 Componenthierachy를 알아야 합니다.
2-1)Component hierachy
-기존의 Daager2와 달리 안드로이드 환경에서 표준적으로 사용하는 Component들을
Hilt에서는 기본적으로 제공합니다.
-Dagger2에서 개발자가 직접적으로 작성해야 하는 초기 Component 세팅 작업을
기본적으로 제공합니다.
각각의 구성요소는 위와 같은 생성위치와 제거 위치를 나타내고 있습니다.
예시1) SingletonComponent
-위의 그림처럼 Module의 @InstallIn 어노테이션을 사용해 '그림1' Component들을
정의할 수 있습니다.
-InsatllIn안에 SingletonComponent를 정의하면 Activity, Fragment, Service,
ViewModel등 어디서나 위의 그림에 정의한 providesTestClass() 메서드로
TestClass 객체를 생성할 수 있습니다.
-또한 SingletonComponent를 사용했기 때문에 사용하는 클래스에 정의된 메서드에는
모두 @singleton 어노테이션을 붙여주어야 합니다.
-메서드 위에 @Singleton 어노테이션을 붙임으로써 객체를 재생성하지 않고 처음 한번
생성 후에 생성한 객체를 재사용합니다.
예시2) ActivityComponent
-만약 InstallIn의 Component를 ActivityComponent로 정의한다면 클래스 내부에
정의된 메서드에는 @ActivityScoped 어노테이션을 붙여야합니다.
-정의한 모듈은 Activity내에서만 사용할 수 있습니다.
ActiivtyRetainedComponent
-이 컴포넌트의 경우 ViewModel의 생명주기 처럼 화면회전에 의해서 소멸되지 않고
엑티비티가 완전히 소멸되어야만 소멸되는 Component입니다.
-@Provides 어노테이션의 역할에 대해서 궁금하실텐데요 @Provides 어노테이션을
이해하기 위해서 먼저 의존성 주입방식에 대해서 알아보겠습니다.
3)의존성 주입 방식
-의존성 주입에는 두 가지 방법이 있습니다.
1-1)생성자 주입
-위의 코드처럼 객체의 생성자에 주입하는 방식을 생성자 주입방식이라고 얘기합니다.
-@Inject constructor 키워드를 입력해서 정의해놓은 모듈에 정의해놓은 객체를 주입
받을 수 있습니다.
1-2)필드 주입
-Activity나 Fragment의 경우 안드로이드 시스템에서 객체를 인스턴스화 하기 때문에
@inject Constructor를 사용해 의존성을 주입받을 수 없습니다.
-이러한 경우 주로 필드 주입을 하게됩니다.
-@Inject 키워드를 사용해서 Filed 주입을 할 수 있습니다.
4)@Provides, @Bind를 사용하는 이유
-위의 그림처럼 Module을 통해 의존성 객체를 전달받지 않고 전달하는
클래스에서 @Inject Constructor를 입력하고 전달받는 Fragment나
Activity에 @Inject를 사용해 객체를 전달받을 수 있습니다.
4-1)외부라이브러리 및 인터페이스의 경우
-그러나 Room이나 Retrofit처럼 생성하려는 클래스가 외부라이브러리에서
제공받는 경우에는 @Inject Constructor를 붙일 수 없기 때문에
Module 클래스를 만들어서 @Binds와 @Provides로
전달할 객체를 작성합니다.
4-1)@Provides
-Room이나 Retrofit 같은 외부라이브러리에서 제공되는 클래스 객체를 전달받을 때 사용합니다.
-위의 코드는 build()(builder 패턴)을 사용해서 외부에서 객체를 생성해서 가져오기
때문에 @Inject Constructor를 통한 의존성 주입이 불가능해서
Module을 생성해서 @Provides를 사용한 것입니다.
Object 클래스로 정의하면 좋은 점
-@Provides만 포함되는 모듈인 경우에 object로 생성했을 시 Provider는 최적화된
코드를 제공하며 inline으로 된 코드를 제공합니다.
4-2)@Binds
-@Inject Constructor를 사용할 수 없는 Interface 객체에 대한 모듈을 작성할 때 사용합니다.
-모듈에 정의된 메서드의 입력값에는 repository의 구현체가 들어가고 반환값으론
Repository객체가 반환됩니다.
참고
https://hungseong.tistory.com/29
https://hanyeop.tistory.com/220
https://blog.banksalad.com/tech/migrate-from-koin-to-hilt/
https://velog.io/@sysout-achieve/Android-DI-Framework-%EC%84%A0%ED%83%9D%EC%A7%80Dagger2-Koin-Hilt
'안드로이드 공부 & 앱' 카테고리의 다른 글
안드로이드 인앱 시스템 구축[2편] QR 코드를 통한 시스템 앱 배포 방법 (1) | 2023.07.28 |
---|---|
안드로이드 인앱 시스템 구축[1편] 앱 소유자(Owner) 권한 얻기 (0) | 2023.07.28 |
[안드로이드/Kotlin] DiffUtill + RecyclerView 개념 정리 및 Tip (0) | 2022.05.14 |
안드로이드 CleanArchitecture 개념 정리 및 구현 (0) | 2022.04.21 |
[안드로이드] JetPack Navigation 개념 정리 및 예제 (0) | 2022.04.16 |
댓글