2016-11-22 14 views
13

मैं एक कोर एंड्रॉयड लाइब्रेरी मैं एक CoreComponent विज्ञापन एक CoreModule द्वारा प्रदान की कक्षाओं के उदाहरण सुई @Singleton दायरे का उपयोग करके जहां परिभाषित करने कर रहा हूँ है पर एक ही स्कोप के साथ कई घटक के बीच एक ही उदाहरण प्रदान करें।डैगर 2: अलग पुस्तकालय मॉड्यूल

@Singleton 
@Component(modules = {CoreModule.class}) 
public interface CoreComponent { 
    void inject(SomeClass target); 
} 

@Module 
public class CodeModule { 
    @Singleton 
    @Provides 
    CoreRepository provideCoreRepository() { 
     return new CoreRepositoryImpl(); 
    } 
} 

मैं एक और एंड्रॉयड लाइब्रेरी कि मुख्य लाइब्रेरी पर निर्भर करता है और एक अन्य घटक उपयोग कर रहा है से एक ही @Singleton उदाहरणों का उपयोग करना चाहते हैं।

@Singleton 
@FooScope 
@Component(modules = {CoreModule.class, FooModule.class}) 
public interface FooComponent { 
    void inject(SomeActivity target); 
} 

public class FooActivity extends AppCompatActivity { 
    @Inject 
    public CoreRepository repo; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     injectDependencies(); 
     super.onCreate(savedInstanceState); 
    } 
    [...] 
} 

उपरोक्त कोड बनाता है लेकिन @Singleton गुंजाइश घटक के लिए "स्थानीय" है। दूसरे शब्दों में दो सिंगलटन उदाहरण हैं, एक कोरकंपोनेंट के लिए और एक FooComponent के लिए।

Android Application 
├── Foo Library 
| └── Core Library 
├── Bar Library 
| └── Core Library 
· 
· 
· 
└── Core Library 

मुझे लगता है कि सबसे अच्छा समाधान एक उप-घटक का उपयोग करना चाहिए, लेकिन, दुर्भाग्य से, संभव प्रतीत नहीं होता क्योंकि मुख्य लाइब्रेरी अन्य पुस्तकालयों का कोई दृश्यता है।

वहाँ अगर वर्ग एक ही स्कोप के साथ टिप्पणी की जाती है डैगर साथ घटकों के बीच एक वर्ग का एक ही उदाहरण साझा करने के लिए एक और रास्ता नहीं है?

@Singleton 
@Component(modules = {CoreModule.class}) 
public interface CoreComponent { 
    CoreRepository coreRepository(); 
} 

आपके आवेदन के अंदर इस सिंगलटन-दायरे वाले घटक के लिए एक संदर्भ बनाएँ:: -

+2

आप [घटक निर्भरता] में देखा है में इंजेक्षन कर सकते हैं (http://stackoverflow.com/q/29587130/1426891) अभी तक? [जावाडोक] (https://google.github.io/dagger/api/latest/dagger/Component.html#component-dependencies) यहाँ देखें और ध्यान दें कि आप स्पष्ट रूप से ऐसा है कि आपके CoreComponent पर कुछ अतिरिक्त एक्सेसर तरीकों का पर्दाफाश करने की आवश्यकता हो सकती है कि FooComponent उन्हें कॉल कर सकते हैं। –

+0

चेकआउट https://stackoverflow.com/questions/27036933/how-to-set-up-dagger-dependency-injection-from-scratch-in-android-project जो स्कोप और आश्रित घटकों का उपयोग करने का एक उदाहरण है –

उत्तर

15

अपने CoreComponent से इंजेक्शन साइटें निकालें यह अब बाध्यकारी उजागर इसकी निर्भर घटकों के लिए CoreRepository के लिए की एकमात्र कार्य है

@Scope 
@Retention(RetentionPolicy.RUNTIME) public @interface PerActivity {} 
:
public class MyApplication extends Application { 
    private final CoreComponent coreComponent; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     coreComponent = DaggerCoreComponent 
          .coreModule(new CoreModule()) 
          .build(); 
    } 

    public static CoreComponent getCoreComponent(Context context) { 
     return ((MyApplication) context.getApplicationContext()).coreComponent; 
    } 
} 

एक नया संकरा गुंजाइश बनाएं

एक नया घटक है कि इंजेक्शन साइटों के साथ इस दायरे पूरा पटरियों बनाएं आप चाहते हैं:

@PerActivity 
@Component(dependencies = {CoreComponent.class}) 
public interface ActivityComponent { 
    void inject(FooActivity activity); 

    void inject(BarActivity activity); 
} 

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

public class FooActivity extends AppCompatActivity { 
     @Inject 
     public CoreRepository repo; 

     @Override 
     protected void onCreate(@Nullable Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      CoreComponent coreComponent = MyApplication.getCoreComponent(this); 
      DaggerActivityComponent.builder() 
       .coreComponent(coreComponent) 
       .build() 
       .inject(this); 
     } 
    } 
} 
+0

अरे धन्यवाद बहुत! मुझे ठीक इसी की आवश्यकता थी! क्योंकि मैं भी मुख्य लाइब्रेरी के अंदर CoreRepository इंजेक्षन करने की जरूरत है केवल एक चीज है कि मैं अलग तरह से कर रहा हूँ भी CoreComponent में इंजेक्षन तरीकों बना रहा हो। क्या यह अच्छा नहीं है? क्या मुझे कोर लाइब्रेरी के अंदर उपयोग करने के लिए निर्भरता के साथ एक नया घटक बनाना चाहिए और किसी भी इंजेक्शन के बिना CoreComponent छोड़ देना चाहिए? –

+1

कोर लाइब्रेरी में निर्भरताओं के लिए इच्छित दायरे पर निर्भर करता है। यदि आप केवल ऐप सिंगलेट्स चाहते हैं तो शायद यह ठीक है। जहाँ तक मुझे पता है मैं और अधिक तो एक के बाद एक घटक के लिए निर्भरता scoped नहीं हो सकता, वहाँ एक रास्ता कई के साथ निर्भरता scoped यह काम करने के लिए प्राप्त करने के लिए है: हालांकि मैं व्यक्तिगत रूप से घटक है कि उनके इंजेक्शन साइटों –

+0

एक और सवाल के दायरे को ट्रैक करना चाहते ?उदाहरण के लिए मेरे पास एकाधिक पुस्तकालय हैं, जिनमें प्रत्येक @ सिंगलेटन स्कॉप्ड घटक है और मैं अपने गतिविधि कॉम्पोनेंट के साथ सिंगलटन उदाहरण साझा करने में सक्षम होना चाहता हूं। पुस्तकालय स्वतंत्र हैं और एक-दूसरे को नहीं देखते हैं। –

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