2014-07-09 5 views
8

Dagger을 통해 의존성 주입을 프로젝트에 소개하고 싶습니다. 다음 코드는에 주입 문제를 설명하는 예제로 사용됩니다.단검을 사용하여 정적 클래스에 주입하는 방법은 무엇입니까?

정적 메소드 setupTextView()는 여러 클래스라고 :

public abstract class TextViewHelper { 
    public static void setupTextView(TextView textView, 
            Spanned text, 
            TrackingPoint trackingPoint) { 
     textView.setText(text, TextView.BufferType.SPANNABLE); 
     textView.setMovementMethod(LinkMovementMethod.getInstance()); 
     textView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       MyApp.getTracker().track(trackingPoint); 
      } 
     }); 
    } 
} 

여기 헬퍼 메소드를 사용하는 방법을 일례이다

TextViewHelper.setupTextView(this, R.id.some_text_view, 
          R.string.some_text, 
          TrackingPoint.SomeTextClick); 

헬퍼 메소드에서 사용 트래킹은에 의해 제공된다 응용 프로그램 클래스 :

public class MyApp extends Application { 

    private static Tracking mTracking; 

    public void onCreate() { 
     super.onCreate(); 
     mTracking = getTracking(getApplicationContext()); 
    } 

    private Tracking getTracking(Context context) { 
     if (BuildConfig.DEBUG) { 
      return new NoTracking(); 
     } else { 
      return new NsaTracking(context); 
     } 
    } 

    public static Tracking getTracker() { 
     return mTracking; 
    } 

} 

이제 tr 단검을 통해 acking.

TextViewHelper.setupTextView(this, R.id.some_text_view, 
          R.string.some_text, 
          TrackingPoint.SomeTextClick, 
          Tracking tracking); 

이 좋은 디자인처럼 생각하지 않습니다 내가 코드를 리팩토링 할 때 내가 직접 정적 클래스에 주입 할 수 없기 때문에 내가 정적 도우미 내 활동이나 조각에서 추적 개체를 전달할 필요가 나타났습니다 패턴 - 이후 TrackPointTracking 개체를 전달합니다. 이걸 어떻게 개선할까요?

+7

NsaTracking? -) – ligi

답변

12

TextViewHelper에는 추적기로 정적 필드를 만듭니다.

@Module(staticInjections = TextViewHelper.class) 
public class TrackerModule { 
... 
} 

그리고 그래프에서 가장 중요한 통화 injectStatics : 여기

public class TextViewHelper { 

    private TextViewHelper(){} 

    @Inject 
    static Tracking sTracker; 

    public static void setupTextView(TextView textView, 
            Spanned text, 
            TrackingPoint trackingPoint) { 
     textView.setText(text, TextView.BufferType.SPANNABLE); 
     textView.setMovementMethod(LinkMovementMethod.getInstance()); 
     textView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       sTracker.track(trackingPoint); 
      } 
     }); 
    } 
} 

모듈을 구성하는 방법입니다.

mObjectGraph = ObjectGraph.create(new TrackerModule()); 
mObjectGraph.injectStatics(); 

편집 :

당신이 단검의 문서는 정적 주사 가. "정적 종속성을 테스트하고 재사용하기 어렵 기 때문에 아껴서 사용되어야"한다고 언급 한 바와 같이 모두 사실이지만, 유틸리티 클래스에 객체를 삽입하는 방법을 물었 기 때문에 이것이 최선의 해결책입니다.

그러나 당신이 당신의 코드를 더 테스트 할 수 있도록하려면, 모듈 아래와 같이 작성 :이 유틸리티 클래스가 단검을 사용하여 주입되기 때문에

@Module(injects = {classes that utilizes TextViewHelper}) 
public class TrackerModule { 

     @Provides 
     Tracking provideTracker() { 
      ... 
     } 

     @Provides 
     @Singleton 
     TextViewHelper provideTextViewHelper(Tracking tracker) { 
      return new TextViewHelper(tracker); 
     } 
} 

지금 당신이 static TextViewHelper에서 방법을 제거 할 수 있습니다.

public class TextViewHelper { 

    private final Tracking mTracker; 

    public TextViewHelper(Tracking tracker){ 
     mTracker = tracker; 
    } 

    public void setupTextView(TextView textView, 
           Spanned text, 
           TrackingPoint trackingPoint) { 
     ... 
    } 
} 

우수 사례를 따르고 자한다면이 방법을 따라야합니다. 두 가지 솔루션 모두 작동하므로 선택해야 할 문제가 있습니다.

+1

** 정적 주사 ** [단검 문서] (http://square.github.io/dagger/#using)는 다음과 같이 명시합니다. * "이 기능은 정적 의존성을 테스트하고 재사용하기가 어렵습니다. "*. 이것을 잘 테스트 할 수 있다고 생각하십니까? – JJD

+0

내 생각에 TextViewHelper는 정적 메서드를 사용하는 클래스가 아니어야합니다. 주입 할 다른 물체로 취급하십시오. 따라서 더 이상 정적 주입이 필요하지 않습니다. 모듈에 두 개의 메서드를 만듭니다. 하나는 Tracker를 제공하고 다른 하나는 TextViewHelper를 제공합니다.TextViewHelper가 필요한 클래스에서 @Inject로 필드를 만듭니다. 이렇게하면 코드를 테스트 할 수 있고 정적 주입이 필요하지 않습니다. – tomrozb

관련 문제