2015-03-13 16 views
6

में 2 अलग-अलग दायरों सम्मिलित करें मैं एक आवेदन विस्तृत सिंगलटन प्रदाता के रूप में moduleA सेटअप, ModuleB एक उपयोगकर्ता से संबंधित वस्तु प्रदाताडैगर वी 2: एक वस्तु

मेरे उपयोगकर्ता प्रदर्शन टुकड़ा दूसरों को संदेश भेजने के लिए प्रणाली विस्तृत बस का उपयोग करेगा के रूप में और प्रदर्शित करने के लिए उपयोगकर्ता से संबंधित वस्तु का उपयोग करें।

समस्या एक ऑब्जेक्ट में अलग-अलग स्क्रॉप कक्षा को इंजेक्ट नहीं कर सकती है। घटक का उपयोग करें .getX विधि ठीक काम करता है, लेकिन इंजेक्ट पसंदीदा तरीका है। त्रुटि संदेश: @UserScope अंतर स्कोप के साथ बाइंडिंग का संदर्भ नहीं हो सकता है: @Provides @Singleton बस ModuleA.provideBus()

@Module 
public class ModuleA { 
    @Provides @Singleton Bus provideBus() {...} 
} 

मॉड्यूल बी उपयोगकर्ता से संबंधित जानकारी प्रदाता

@Module 
public class ModuleB{ 
    private final User user; 
    public ModuleB(User user) {...} 
    @Provides @UserScope User provideUser() {} 
    @Provides @UserScope UserManager provideUserManager() {} 
} 

अवयव सेटअप के रूप में निम्नलिखित की तरह:

@Component (modules={ModuleA.class}) 
@Singleton 
public interface ComponentA { 
    Bus getBus(); 
    void inject(ClassA target); 
} 

@Component(modules={ModuleB.class}) 
@UserScope 
public interface ComponentB { 
    User getUser(); 
    UserManager getUserManager(); 
    void inject(ClassA target); 
} 


class UserFragment exrtends Fragment { 
    @Inject Bus bus; 
    @Inject UserManager userManager; 
    public void onCreate() { 
     getComponentA().inject(this); 
     getComponentB().inject(this); 
    } 
} 

उत्तर

20

इस विन्यास की कोशिश करें, यह मेरे लिए काम करता । वास्तव में डैगर 2 के बारे में अच्छी प्रलेखन की कमी है इसलिए मैंने कोड के कुछ ओपन-सोर्स उदाहरणों का अध्ययन किया जिन्हें आप गिटहब आदि में खोज सकते हैं जैसे डैगर 2।

आवेदन स्तर घटक

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    // exported for child-components 
    Bus eventBus(); 
} 

आवेदन स्तर मॉड्यूल

@Module 
public class AppModule { 
    @Provides @Singleton 
    Bus provideBus() { 
     return BusProvider.getInstance(); 
    } 
} 

गतिविधि स्तर घटक

@ActivityScope 
@Component(dependencies=AppComponent.class, modules=MainActivityModule.class) 
public interface MainActivityComponent { 
    void inject(MainActivity mainActivity); 
} 

गतिविधि स्तर मॉड्यूल

@Module 
public class MainActivityModule { 
    private final MainActivity mActivity; 

    public MainActivityModule(MainActivity activity) { 
     mActivity = activity; 
    } 

    @Provides 
    MainActivityTitleController provideTitleController() { 
     return new MainActivityTitleController(mActivity); 
    } 
} 

एंड्रॉयड आवेदन वर्ग

public class MyApplication extends Application { 
    private AppComponent mAppComponent; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // Dagger2 
     mAppComponent = Dagger_AppComponent.builder() 
      .appModule(new AppModule(this)) 
      .build(); 
    } 

    public AppComponent getComponent() { 
     return mAppComponent; 
    } 

    public static AppComponent getComponent(Context context) { 
     return ((MyApplication)context.getApplicationContext()).getComponent(); 
    } 
} 

और अंत में गतिविधि

public class MainActivity extends ActionBarActivity { 

    // Injectable fields 
    @Inject Bus mEventBus; 
    @Inject MainActivityTitleController mTitleController; 

    private MainActivityComponent mComponent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // Dagger2 
     mComponent = Dagger_MainActivityComponent.builder() 
      .appComponent(((MyApplication)getApplication()).getComponent()) 
      .mainActivityModule(new MainActivityModule(this)) 
      .build(); 
     mComponent.inject(this); 
    } 
} 
+4

क्या होगा यदि 'MainActivityComponent' एक सबकंपोनेंट है? –

7

मैं अपने कोड के टुकड़े आपके द्वारा दी गई में मुख्य समस्या यह है लगता है, जो आपके ModuleBModuleA पर निर्भरता को सही ढंग से सिंगलटन प्रदान करने के लिए होना चाहिए आप जो त्रुटि प्राप्त कर रहे थे उसके साथ। अर्थात। यह काम करना चाहिए:

@Component(modules={ModuleB.class}, dependencies = ComponentA.class) 
@UserScope 
public interface ComponentB { 
    User getUser(); 
    UserManager getUserManager(); 
    void inject(MainActivity target); 
} 

मैंने अपनी कक्षाएं बनाई और रिक्त स्थान भरने के लिए कुछ धारणाएं कीं, और ऐसा लगता है कि यह ठीक काम करता है। आप पूर्ण कार्य कोड here on GitHub देख सकते हैं। मेरे कोड में एकमात्र अंतर है, जिसे आपने ClassA/UserFragment कहा है, मैंने अभी MainActivity कहा है लेकिन अन्यथा संरचना समान है।

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