2016-12-11 9 views
6

डैगर 2 सीखने के लिए मैंने अपने आवेदन को फिर से लिखने का फैसला किया लेकिन मैं निम्नलिखित समस्या के लिए उचित समाधान ढूंढने के साथ अटक गया हूं।डैगर 2: रनटाइम पर प्रदत्त निर्भरताओं को कैसे बदलें

इस उदाहरण के प्रयोजन के मान लेते हैं कि हम एक अंतरफलक Mode कहा जाता है जाने के लिए:

public interface Mode { 
    Object1 obj1(); 

    //some other methods providing objects for app 
} 

और दो कार्यान्वयन: NormalMode और DemoMode

मोड सिंगलटन में संग्रहीत किया जाता है ताकि इसे एप्लिकेशन के भीतर कहीं से भी एक्सेस किया जा सके।

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 को DemoModeModule के साथ डीएजी में बदलना चाहता हूं, इसलिए Object1 की अन्य कक्षाओं को अब से DemoObject1 कार्यान्वयन मिलेगा।

मैं डैगर में ऐसा कैसे कर सकता हूं?

अग्रिम धन्यवाद।

+0

की [डैगर साथ swappable मॉड्यूल संभावित डुप्लिकेट 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. AppComponent

    को
    @Singleton 
    @Component(modules = {AppModule.class, ConfModule.class}) 
    public interface AppComponent { 
        //... 
    } 
    
  4. मॉड्यूल जोड़ें
  5. मॉड्यूल जो रनटाइम के दौरान मोड स्विच करने के लिए मोड

    @Module 
    public class Object1Module { 
    
        @Provides 
        Object1 provideObject1(Conf conf) { 
        if (conf.mode == Conf.Mode.NORMAL) 
         return new NormalObject1(); 
        else 
         return new DemoObject1(); 
        } 
    } 
    
  6. के आधार पर विभिन्न वस्तुओं को उपलब्ध कराने को परिभाषित करें बस Conf वस्तु इंजेक्षन और इसे संशोधित:

    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

ऐसा करने के लिए एक सभ्य तरीका लगता है, लेकिन यह तब तक काम नहीं करेगा जब प्रदान की गई निर्भरता (जिसे प्रतिस्थापित किया जाएगा रनटाइम पर डी) एक सिंगलटन है, है ना? –

+1

हां, यदि आप '@ सिंगलटन 'के साथ' प्रदान ऑब्जेक्ट 1 'को एनोटेट करेंगे तो यह काम नहीं करेगा, लेकिन दूसरी ओर यह इस उपयोग के मामले में विचार के विपरीत है। यदि आप रनटाइम पर ऑब्जेक्ट्स को प्रतिस्थापित करना चाहते हैं तो आप इस तरह की विधि को '@ सिंगलटन' के साथ चिह्नित नहीं कर सकते हैं। दूसरी तरफ आप 'NormalObject1' और 'DemoObject1' सिंगलेट्स बना सकते हैं, इसलिए निर्भरता प्रदान करने वाली विधि 2 से अधिक उदाहरण नहीं बनाएगी। – Marcin

+0

वह अंतिम वाक्य मुझे आवश्यक जानकारी थी। महान समाधान, thx :) –

संबंधित मुद्दे