2016-12-11 58 views
6

Hançer 2'yi öğrenmek için başvurumu yeniden yazmaya karar verdim, ancak aşağıdaki sorun için uygun çözümü bulmaya çalışıyorum.Hançer 2: çalışma zamanında sağlanan bağımlılıkları nasıl değiştirilir?

public interface Mode { 
    Object1 obj1(); 

    //some other methods providing objects for app 
} 

ve iki uygulamaları: NormalMode ve DemoMode

Bu örneğin amacı en biz Mode adlı bir arayüze sahip varsayalım için

.

Mod tekil olarak kaydedilir, böylece uygulama içindeki herhangi bir yerden erişilebilir.

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 zamanında DemoMode geçer (diyelim ki, ne zaman kere arka plan çift kullanıcı clickcs)

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

Yani

ilk ben tekiz kurtulmak ve sıra Modlar tanımlanmış var Hançer 2 modülleri:

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

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

Artık backgroundClicked5Times yönteminde singleton ile uğraşmak yerine 'u DemoModeModule DAG ile değiştirmek istiyorum, bu yüzden Object1'a ihtiyaç duyan diğer sınıflar artık bir DemoObject1 uygulamasına sahip olacaklar.

Bunu Hançer'de nasıl yapabilirim?

Şimdiden teşekkürler.

+0

Olası yinelenen 2] (https://stackoverflow.com/questions/35658488/swappable-modules-with-dagger-2) – tir38

cevap

1

Bir süreliğine hançer denemeyi denedim, kullanım durumumda iyi çalışıyor gibi görünen bir çözüm buldum.

  1. public class Conf { 
        public Mode mode; 
    
        public Conf(Mode mode) { 
        this.mode = mode; 
        } 
    
        public enum Mode { 
        NORMAL, DEMO 
        } 
    } 
    
  2. Modülü Conf tekiz örneğine sağlayın modu hakkında durum bilgilerini tutacaktır sınıfını tanımlamak

    @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

    modülü ekle
  5. basitçe Conf nesne enjekte ve değiştirmek zamanında moduna geçmek amacıyla Mode

    @Module 
    public class Object1Module { 
    
        @Provides 
        Object1 provideObject1(Conf conf) { 
        if (conf.mode == Conf.Mode.NORMAL) 
         return new NormalObject1(); 
        else 
         return new DemoObject1(); 
        } 
    } 
    
  6. dayalı farklı nesneler sağlamak modülleri tanımlayın: Dagger ile Swap modüllerinin [ait

    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

Bunu yapmak için iyi bir yol gibi görünüyor, ancak sağlanan bağımlılık olduğunda bu işe yaramaz. d çalışma zamanında) bir singleton olacak mı? –

+1

Evet, '@ Singleton' ile 'offerObject1' ifadesini ekleyecekseniz, bu işe yaramazdı, ancak diğer yandan bu kullanım örneğindeki fikirle çelişiyor. Eğer nesneleri çalışma zamanında değiştirmek istiyorsanız, böyle bir yöntemi 'Singleton' ile işaretleyemezsiniz. Diğer taraftan, 'NormalObject1' ve' DemoObject1' single'larını yapabilirsiniz, böylece bağımlılık sağlayan yöntem 2'den fazla örnek oluşturamaz. – Marcin

+0

Bu son cümle, ihtiyacım olan bilgilerdi. Harika çözüm, thx :) –