Dagger2 Basics - 너도 DI 할래?

l2hyunwoo·2021년 4월 21일
0

Android 기능 구현

목록 보기
12/12
post-thumbnail

Dagger2

Dagger2 Basics

코드가 Dependency Injection에 필요한 코드를 컴파일 타임에 만들어 traceable + reflection 기반의 DI 컴포넌트보다 퍼포먼스가 좋음

Benefits of using Dagger

  • AppContaioner Code(Application Graph)를 직접 만들어줌
  • 객체를 생성시킬 수 있는 팩토리를 만들어줌
  • Scope를 정해서 dependency를 재사용할 지, 새로운 객체를 만들 지 결정할 수 있음
  • 특정 플로우에[ 대한 컨테이너들을 만들 수 있음

A simple use case in Dagger: Generating a factory

@Inject 어노테이션을 사용하여 객체를 어떻게 만드는 지 Dagger2로 하여금 알게함

// @Inject lets Dagger know how to create instances of this object
class UserRepository @Inject constructor(
    private val localDataSource: UserLocalDataSource,
    private val remoteDataSource: UserRemoteDataSource
) { ... }

Dagger Components

Dagger는 Dependency Graph를 만들어서 어디서 이런 dependency들을 가져올 수 있는 지 알게 해준다.

@Component 어노테이션을 사용하여 수동으로 DI를 할 때 사용했던 Container를 만들어준다.

// @Component makes Dagger create a graph of dependencies
@Component
interface ApplicationGraph {
    // The return type  of functions inside the component interface is
    // what can be provided from the container
    fun repository(): UserRepository
}

프로젝트를 빌드할 때, Dagger는 ApplicationGraph의 구현체인 DaggerApplicationGraph 클래스를 만든다.

이 UserRepository를 가져오기 위한 종속 관계를 정의한 그래프는 Dagger가 만들어줌

// Create an instance of the application graph
val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()
// Grab an instance of UserRepository from the application graph
val userRepository: UserRepository = applicationGraph.repository()

디폴트가 싱글턴은 아닌 듯 그래서 scope annotation을 활용하여 동일한 인스턴스를 사용할 것을 알려줘야한다(Scoping with Dagger에서 나옴)

val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()

val userRepository: UserRepository = applicationGraph.repository()
val userRepository2: UserRepository = applicationGraph.repository()

// 이거 true
assert(userRepository != userRepository2)

Scoping with Dagger

Scope Annotation -> Instance의 생명주기를 이에 종속된 컴포넌트의 생명주기로 제한시킬 수 있음

// Scope annotations on a @Component interface informs Dagger that classes annotated
// with this annotation (i.e. @Singleton) are bound to the life of the graph and so
// the same instance of that type is provided every time the type is requested.
@Singleton
@Component
interface ApplicationGraph {
    fun repository(): UserRepository
}

// Scope this class to a component using @Singleton scope (i.e. ApplicationGraph)
@Singleton
class UserRepository @Inject constructor(
    private val localDataSource: UserLocalDataSource,
    private val remoteDataSource: UserRemoteDataSource
) { ... }
profile
이현우의 개발 브이로그

0개의 댓글