ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Hilt를 이용한 Dependency Injection(DI) - 2
    안드로이드 2021. 7. 8. 16:59
    반응형

    Android 클래스용으로 생성된 구성요소

    @InstallIn에 사용하는 Component로 [안드로이드] - Hilt를 이용한 Dependency Injection(DI) - 1 포스팅에서 ActivityComponent를 사용하는 예제코드를 작성했다. Component에 대한 설명은 아래와 같다.

     

     

    Component 대상 및 기간

    Hilt Component 인젝터 대상 생성 위치 제거 위치
    ApplicationComponent Application Application#onCreate() Application#onDestroy()
    ActivityRetainedComponent ViewModel Activity#onCreate() Activity#onDestroy()
    ActivityComponent Activity Activity#onCreate() Activity#onDestroy()
    FragmentComponent Fragment Fragment#onAttach() Fragment#onDestroy()
    ViewComponent View View#super() View destroyed
    ViewWithFragmentComponent @WithFragmentBindings
    주석이 지정된 View
    View#super() View destroyed
    ServiceComponent Service Service#onCreate() Service#onDestroy()

     

    Component 범위

    기본적으로 Hilt는 앱이 결합을 요청할 때 마다 인스턴스를 새로 생성한다.

    그러나 Hilt는 결합을 특정 Component로 범위를 지정할 수 있다. 범위가 지정된 Component는 해당 범위 내에서는 동일한 인스턴스를 공유한다.

     

    아래 표는 Component의 범위 Annotation을 보여준다.

    Android 클래스 생성된 Component 범위
    Application ApplicationComponent @Singleton
    View Model ActivityRetainedComponent @ActivityRetainedScope
    Activity ActivityComponent @ActivityScoped
    Fragment FragmentComponent @FragmentScoped
    View ViewComponent @ViewScoped
    @WithFragmentBindings 주석이 지정된 View ViewWithFragmentComponent @ViewScoped
    Service ServiceComponent @ServiceScoped

    예제 코드

    @ActivityScoped
    class AnalyticsAdapter @Inject constructor(
      private val service: AnalyticsService
    ) { ... }

    위 코드에서 @AcitivityScoped를 사용했는데 이는 Activity 생명주기 동안 동일한 AnlysticsAdapter 인스턴스를 사용한다는 의미이다.

     

    앱의 모든 위치에서 동일한 인스턴스를 사용해야한다면(Singleton 패턴을 사용해야 한다면) 아래의 예제와 같이 설정해줘야 한다.

    // If AnalyticsService is an interface.
    @Module
    @InstallIn(ApplicationComponent::class)
    abstract class AnalyticsModule {
    
      @Singleton
      @Binds
      abstract fun bindAnalyticsService(
        analyticsServiceImpl: AnalyticsServiceImpl
      ): AnalyticsService
    }
    
    // If you don't own AnalyticsService.
    @Module
    @InstallIn(ApplicationComponent::class)
    object AnalyticsModule {
    
      @Singleton
      @Provides
      fun provideAnalyticsService(): AnalyticsService {
          return Retrofit.Builder()
                   .baseUrl("https://example.com")
                   .build()
                   .create(AnalyticsService::class.java)
      }
    }

    @InstallIn 어노테이션에서 Component는 ApplicationComponent를 사용하고 모듈 내의 함수에서는 @Singleton 어노테이션을 추가해준다.

     

    Component 계층 구조

    Component에 모듈을 설치하면 Component 계층 구조 상 하위 Component에서 상위 Component에 종속 항목을 Binding 할 수 있게 접근이 가능하다.

    Componet 기본 Binding

    각 Hilt Component는 Hilt가 자신의 Custom Binding에 Dependency로 주입할 수 있는 기본 Binding 세트가 함께 제공된다. 이 Binding은 특정 Subclass가 아닌 일반 Activity와 Fragment 타입에 해당한다. 이는 Hilt가 모든 Activity에 주입하기 위한 단일 Activity Component 정의를 사용하기 때문이다. 각 Activity는 해당 Component에 다른 인스턴스를 가지고 있다.

    Android Component 기본 Binding
    ApplicationComponent Application
    ActivityRetainedComponent Application
    ActivityComponent Application, Activity
    FragmentComponent Application, Activity, Fragment
    ViewComponent Application, Activity, View
    ViewWithFragmentComponent Application, Activity, Fragment, View
    ServiceComponent Application, Service

    애플리케이션 Context Binding은 @ApplicationContext를 통해 사용할 수 있고, Activity Context Binding은 @ActivityContext를 통해 사용할 수 있다. 예제코드는 아래와 같다.

    // -- Application Context Binding
    class AnalyticsServiceImpl @Inject constructor(
      @ApplicationContext context: Context
    ) : AnalyticsService { ... }
    
    // The Application binding is available without qualifiers.
    class AnalyticsServiceImpl @Inject constructor(
      application: Application
    ) : AnalyticsService { ... }
    // Application Context Binding --
    
    // -- Activity Context Binding
    class AnalyticsAdapter @Inject constructor(
      @ActivityContext context: Context
    ) { ... }
    
    // The Activity binding is available without qualifiers.
    class AnalyticsAdapter @Inject constructor(
      activity: FragmentActivity
    ) { ... }
    // Activity Context Binding --

     

     

    반응형

    댓글

Designed by Tistory.