ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Hilt 이해를 위한 Dagger 기반지식 쌓기1
    IT/android 2024. 12. 8. 20:48
    SMALL

    서론..

    모든 애플리케이션에서 가장 훌륭한 클래스는 실제로 무언가를 수행하는 클래스들입니다. BarcodeDecoder, KoopaPhysicsEngine, AudioStreamer와 같은 것들이죠. 이러한 클래스들은 BarcodeCameraFinder, DefaultPhysicsEngine, HttpStreamer 같은 의존성들을 가지고 있습니다.

    반면, 애플리케이션에서 가장 좋지 않은 클래스들은 실제로는 별로 하는 일 없이 공간만 차지하는 것들입니다. BarcodeDecoderFactory, CameraServiceLoader, MutableContextWrapper 같은 것들이죠. 이런 클래스들은 흥미로운 부분들을 어설프게 연결하는 덕트 테이프 같은 존재입니다.

    Dagger는 이러한 FactoryFactory 클래스들을 대체하여, 보일러플레이트 코드 없이도 의존성 주입 디자인 패턴을 구현할 수 있게 해줍니다. 이를 통해 여러분은 진짜 중요한 클래스들에 집중할 수 있습니다. 의존성을 선언하고, 그것을 만족시키는 방법을 명시한 다음, 앱을 배포하면 됩니다.

    표준 javax.inject 어노테이션(JSR 330)을 기반으로 하기 때문에, 각 클래스는 테스트하기 쉽습니다. RpcCreditCardService를 FakeCreditCardService로 교체하기 위해 많은 보일러플레이트 코드를 작성할 필요가 없죠.

    의존성 주입은 테스트만을 위한 것이 아닙니다. 재사용 가능하고 교체 가능한 모듈을 만드는 것도 쉽게 해줍니다. 모든 앱에서 동일한 AuthenticationModule을 공유할 수 있고, 개발 중에는 DevLoggingModule을, 프로덕션에서는 ProdLoggingModule을 실행하여 각 상황에 맞는 올바른 동작을 얻을 수 있습니다.

    Dagger 2가 다른 이유

    의존성 주입 프레임워크들은 다양한 API로 구성과 주입을 처리하면서 수년간 존재해왔습니다. 그렇다면 왜 바퀴를 다시 발명해야 할까요? Dagger 2는 생성된 코드로 전체 스택을 구현한 최초의 프레임워크입니다. 사용자가 직접 작성했을 법한 코드를 모방하는 코드를 생성하여, 의존성 주입을 가능한 한 단순하고, 추적 가능하며, 성능이 좋게 만드는 것이 핵심 원칙입니다.

     

    코드 예제를 통해 의존성 주입과 Dagger가 무엇인지 알아보겠습니다. 커피 메이커를 만들어보면서 설명하겠습니다. (전체 예제 코드는 Dagger의 coffee 예제를 참고하세요.)

    의존성 선언하기

    Dagger는 애플리케이션 클래스의 인스턴스를 생성하고 그들의 의존성을 만족시킵니다. Dagger는 javax.inject.Inject 어노테이션을 사용해 어떤 생성자와 필드에 관심이 있는지 파악합니다.

    @Inject를 사용하여 Dagger가 클래스의 인스턴스를 생성할 때 사용해야 하는 생성자를 지정합니다. 새로운 인스턴스가 요청되면, Dagger는 필요한 파라미터 값들을 가져와서 이 생성자를 호출합니다.

    class Thermosiphon implements Pump {
      private final Heater heater;
    
      @Inject
      Thermosiphon(Heater heater) {
        this.heater = heater;
      }
      ...
    }

    Dagger는 필드에 직접 주입할 수도 있습니다. 이 예제에서는 heater 필드를 위한 Heater 인스턴스와 pump 필드를 위한 Pump 인스턴스를 가져옵니다.

    class CoffeeMaker {
      @Inject Heater heater;
      @Inject Pump pump;
      ...
    }

    클래스에 @Inject가 붙은 필드는 있지만 @Inject가 붙은 생성자가 없다면, Dagger는 요청 시 해당 필드들을 주입할 수는 있지만 새로운 인스턴스는 생성하지 않습니다. @Inject 어노테이션이 붙은 인자 없는 생성자를 추가하면 Dagger가 인스턴스도 생성할 수 있다는 것을 나타냅니다.

    Dagger는 메서드 주입도 지원하지만, 일반적으로는 생성자나 필드 주입이 선호됩니다.

    @Inject 어노테이션이 없는 클래스는 Dagger가 생성할 수 없습니다.

     

    의존성 만족시키기

    기본적으로 Dagger는 위에서 설명한 것처럼 요청된 타입의 인스턴스를 생성하여 각 의존성을 만족시킵니다. CoffeeMaker가 요청되면, new CoffeeMaker()를 호출하고 주입 가능한 필드들을 설정합니다.

    하지만 @Inject는 모든 상황에서 작동하지 않습니다:

    • 인터페이스는 인스턴스화할 수 없습니다
    • 서드파티 클래스는 어노테이션을 추가할 수 없습니다
    • 설정이 필요한 객체는 반드시 설정되어야 합니다!

    이렇게 @Inject가 충분하지 않거나 적절하지 않은 경우, @Provides 어노테이션이 달린 메서드를 사용하여 의존성을 만족시킬 수 있습니다. 메서드의 반환 타입이 어떤 의존성을 만족시키는지 정의합니다.

    예를 들어, Heater가 필요할 때마다 provideHeater()가 호출됩니다:

    @Provides 
    static Heater provideHeater() {
      return new ElectricHeater();
    }

     

    @Provides 메서드도 자신만의 의존성을 가질 수 있습니다. 예를 들면, ElectricHeater 가 @Inject 생성자를 가지고 있다면, 위 메서드는 다음과같이 작성될 수 있습니다.

    @Provides 
    static Heater provideHeater(ElectricHeater heater) {
      return heater;
    }

     

    이렇게 하면  Dagger 가 ElectricHeater 의 인스턴스화를 처리하고, @Provides 메서드는 단지 이를 Heater 타입을 ㅗ연결하는 데만 사용합니다. 

     

    이 특정 케이스 에서는 @Binds 메서드를 사용하여 더 간단하게 연결을 정의할 수 있습니다. 

    @Provides와 달리 @Binds 메서드는 추상 메서드이며 구현이 없습니다.

    @Binds Heater bindHeater(ElectricHeater impl);

     

    참고: @Binds는 연결을 정의하는 데 선호되는 방식입니다. Dagger는 컴파일 타임에만 모듈이 필요하고, 런타임에 모듈의 클래스 로딩을 피할 수 있기 때문입니다.

    마지막으로, 모든 @Provides와 @Binds 메서드는 모듈에 속해야 합니다. 모듈은 단순히 @Module 어노테이션이 달린 클래스입니다.

    @Module
    interface HeaterModule {
      @Binds Heater bindHeater(ElectricHeater impl);
    }

     

    references :: https://dagger.dev/dev-guide/

     

    Dagger

    The best classes in any application are the ones that do stuff: the BarcodeDecoder, the KoopaPhysicsEngine, and the AudioStreamer. These classes have dependencies; perhaps a BarcodeCameraFinder, DefaultPhysicsEngine, and an HttpStreamer. To contrast, the w

    dagger.dev

     

    LIST

    'IT > android' 카테고리의 다른 글

    Gradle 훑어보기1 - 기본사항  (1) 2024.12.14
    DoveLetter interview question 훑어보기1  (1) 2024.12.09
    Hilt 공식문서 훑어보기2 Hilt Components  (0) 2024.12.08
    Hilt 공식문서 훑어보기1  (0) 2024.12.08
    Composable의 수명주기  (0) 2024.11.21
Designed by Tistory.