RoboGuice 사용시에 클래스 타입만으로는 주입받을 모듈을 구분하기 어려운 경우가 있습니다. 

예들들어 시간이 오래걸리는 작업을 처리하는 동안 사용자에게 진행중임을 알려주는 다이얼로그가 필요해서 아래처럼 Dialog를 주입받는 코드를 작성했습니다.


@Inject

protected Dialog progressDialog;


위 코드에서 우리가 원하는 것은 작업이 진행중임을 알려주는 Dialog를 주입시키는 것입니다. 그러나 다른 모듈에서는 다른 모양의 Dialog가 주입되어야 하는데 저 Dialog 타입만으로는 그것을 구분할 수 없습니다.


이런 상황에서는 추가적인 정보를 제공하는 어노테이션을 이용하면 됩니다. 위 예제의 경우 먼저 @TaskProgressDialog와 같은 어노테이션을 만들어 추가해줍니다.  


@Inject

@TaskProgressDialog

protected Dialog progressDialog;


그리고 Guice 모듈설정에서 AnnotatedBindingBuilder.annotatedWith() 메소드를 통해 해당 어노테이션이 붙은 놈에 적절한 모듈을 주입합니다.


protected void configure() {

  bind(Dialog.class).annotatedWith(TaskProgressDialog.class).toProvider(TaskProgrerssDialogProvider.class);

  ... ...

}


이렇게 하면 Dialog 타입이면서 @TaskProgressDialog 어노테이션이 붙어 있는 놈한테만 TaskProgressDialogProvider가 생성한 Dialog 객체가 주입될 것입니다.


* 참고로, Guice는 문자열을 통해 어노테이션을 구분할 수 있는 @Named 어노테이션을 제공합니다. 그러니까 필요시마다 TaskProgressDialog 같은 별도의 어노테이션 클래스를 만들 필요가 없다는 얘기입니다. 단, 문자열이 이용되므로 보조적인 수단으로만 사용을 권장합니다.


public class RealBillingService implements BillingService {

  @Inject

  public RealBillingService(@Named("Checkout") CreditCardProcessor processor,

      TransactionLog transactionLog) {

    ...

  }


Guice 모듈설정에서는 Names.named() 를 이용합니다.


bind(CreditCardProcessor.class).annotatedWith(Names.named("Checkout")).to(CheckoutCreditCardProcessor.class);






Posted by 에코지오
,