2016-12-11 4 views
6

단검 2를 배우려면 애플리케이션을 다시 작성하기로 결정했지만 다음 문제에 대한 적절한 해결책을 찾지 못했습니다.단검 2 : 런타임에 제공된 종속성을 변경하는 방법

public interface Mode { 
    Object1 obj1(); 

    //some other methods providing objects for app 
} 

과 두 가지 구현 : NormalModeDemoMode

이 예제의 목적은의 우리가 Mode라는 인터페이스가 있다고 가정하자를 들어

.

모드는 싱글 톤으로 저장되므로 응용 프로그램 내 어디에서나 액세스 할 수 있습니다.

public enum ModeManager { 
    INSTANCE,; 

    private Mode mode; 

    public Mode mode() { 
    if (mode == null) 
     mode = new NormalMode(); 
    return mode; 
    } 

    public void mode(Mode mode) { //to switch modules at runtime 
    this.mode = mode; 
    } 
} 

NormalMode는 런타임에 DemoMode로 전환 (의 말을하자, 때 배의 배경 부부 사용자 clickcs)

public void backgroundClicked5Times(){ 
    ModeManager.INSTANCE.mode(new DemoMode()); 
    //from now on every object that uses Mode will get Demo implementations, great! 
} 

그래서

처음에는 싱글 제거하고 같은 모드를 정의있어 단검 2 모듈 :

@Module 
public class NormalModeModule { 
    @Provides 
    public Object1 provideObject1() { 
    return new NormalObject1(); 
    } 
} 

@Module 
public class DemoModeModule { 
    @Provides 
    public Object1 provideObject1() { 
    return new DemoObject1(); 
    } 
} 

이제 backgroundClicked5Times 싱글 톤을 다루는 대신 나는 NormalModeModule을 DAG의 DemoModeModule으로 바꾸고 싶습니다. 따라서 Object1이 필요한 다른 클래스는 DemoObject1 구현을 지금부터 받게 될 것입니다.

대거에서 어떻게 할 수 있습니까?

미리 감사드립니다.

+0

가능한 중복 2] (https://stackoverflow.com/questions/35658488/swappable-modules-with-dagger-2) – tir38

답변

1

잠시 동안 단검을 실험 해본 결과 나는 유스 케이스에서 잘 작동하는 것으로 보이는 솔루션을 생각해 냈습니다.

  1. public class Conf { 
        public Mode mode; 
    
        public Conf(Mode mode) { 
        this.mode = mode; 
        } 
    
        public enum Mode { 
        NORMAL, DEMO 
        } 
    } 
    
  2. 이 모듈에 Conf의 싱글 인스턴스를 제공 모드에 대한 상태 정보를 개최 클래스를 정의

    @Module 
    public class ConfModule { 
        @Provides 
        @Singleton 
        Conf provideConf() { 
        return new Conf(Conf.Mode.NORMAL); 
        } 
    } 
    
  3. @Singleton 
    @Component(modules = {AppModule.class, ConfModule.class}) 
    public interface AppComponent { 
        //... 
    } 
    
  4. AppComponent

    에 모듈을 추가
  5. 단순히 Conf 개체를 삽입하고 수정 런타임시 모드를 전환하려면 모드

    @Module 
    public class Object1Module { 
    
        @Provides 
        Object1 provideObject1(Conf conf) { 
        if (conf.mode == Conf.Mode.NORMAL) 
         return new NormalObject1(); 
        else 
         return new DemoObject1(); 
        } 
    } 
    
  6. 에 따라 서로 다른 객체를 제공하는 모듈을 정의 : 단검과 스왑 모듈 [의

    public class MyActivity extends Activity { 
        @Inject Conf conf; 
    
        //... 
    
        public void backgroundClicked5Times(){ 
         conf.mode = Conf.Mode.DEMO; 
    
         //if you have dagger objects in this class that depend on Mode 
         //execute inject() once more to refresh them 
        } 
    } 
    
+0

괜찮은 방법처럼 보이지만, 제공된 종속성 (대체 될 것입니다. d는 런타임에) 싱글 톤입니까? –

+1

예,'provideObject1'에'@Singleton'으로 주석을 달면 작동하지 않지만 다른 한편으로는이 유스 케이스의 아이디어와 모순됩니다. 런타임에 객체를 대체하려면'@ Singleton '으로 이러한 메소드를 표시 할 수 없습니다. 반면에'NormalObject1'과'DemoObject1'을 싱글 톤으로 만들면 의존성을 제공하는 메소드가 2 개 이상의 인스턴스를 생성하지 않게 될 것입니다. – Marcin

+0

마지막 문장은 내가 필요한 정보입니다. 좋은 해결책, thx :) –

관련 문제