2016-11-22 38 views
13

Bir CoreModule tarafından sağlanan sınıfların örneklerini enjekte etmek için @Singleton alanını kullanan bir CoreComponent reklamını tanımladığım bir Çekirdek Android Kitaplığım var.Hançer 2: Farklı kütüphane modüllerinde aynı Kapsamlı çoklu Bileşen arasında aynı örneği sağlayın

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

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

Ben Çekirdek Kütüphanesi bağlı olduğu ve başka bir bileşen kullanan başka bir Android Kütüphanesi'nden aynı @Singleton örneklerini erişmek istiyorum. Yukarıdaki kod @Singleton kapsamına ama oluşturur

@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); 
    } 
    [...] 
} 

Bileşen için "yerel" dir. Başka bir deyişle, CoreComponent için bir tane ve FooComponent için bir tane olmak üzere iki tane tekli durum vardır.

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

Bence en iyi çözüm Çekirdek Kitaplığı diğer kütüphanelerin hiçbir görüş vardır, çünkü ne yazık ki, mümkün görünmüyor, bir alt bileşen kullanılarak fakat gerektiğini düşünüyorum.

Sınıf aynı açıklamayla eklenmişse, Dagger ile aynı sınıftaki bir bileşenle paylaşmanın başka bir yolu var mı?

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

uygulama içerisinden bu tekil kapsamına sahip bileşen için bir başvuru oluşturun: -

+2

sen [bileşen bağımlılıkları] baktınız mı senin içine enjekte edebilir (http://stackoverflow.com/q/29587130/1426891) henüz? Burada [Javadoc] 'a bakın (https://google.github.io/dagger/api/latest/dagger/Component.html#component-dependencies) ve CoreComponent'inizde bazı ekstra accessor yöntemlerini açık bir şekilde göstermeniz gerekebileceğini unutmayın. FooComponent onları arayabilir. –

+0

Checkout https://stackoverflow.com/questions/27036933/how-to-set-up-dagger-dependency-injection-from-scratch-in-android-project Örneğin kapsamları ve bağımlı bileşenleri kullanma örneği var –

cevap

15

sizin CoreComponent den enjeksiyon siteleri kaldırın şimdi kendi bağımlı bileşenlerine CoreRepository için bağlayıcı açığa tek işlevi vardır

@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; 
    } 
} 

yeni daha dar bir kapsamı oluşturma

enjeksiyon siteleri ile komple bu kapsam izler yeni bir bileşen oluşturun, istediğiniz:

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

    void inject(BarActivity activity); 
} 

Eğer enjeksiyon sitesinde bu faaliyet kapsamına sahip bileşen eriştiğinizde, oluşturucu CoreComponent örneğini sağlamanız gerekir . Şimdi 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

Hey teşekkürler çok! Bu tam olarak ihtiyacım olan şey! Farklı bir şekilde yaptığım tek şey, CoreComponent'te de enjeksiyon yöntemlerini tutmaktır çünkü Core Library'de CoreRepository'yi de enjekte etmem gerekiyor. Bu hoş değil mi? Çekirdek Kitaplığı içinde kullanmak için ona bağımlı olan yeni bir Bileşen oluşturmalı ve CoreComponent'i hiçbir enjekte etmeden bırakmalı mıyım? –

+1

CoreLibrary'deki bağımlılıklar için istediğiniz kapsama bağlıdır. Sadece içinde uygulama singletonlar varsa o zaman muhtemelen tamam. Ancak, kişisel olarak, enjeksiyon sitelerinin kapsamını izleyen bileşenlere sahip olmaktan hoşlanıyorum –

+0

Bir soru daha: Tek bir Bileşen için birden fazla kapsam bağımlılık yapamayacağımı bildiğim kadarıyla, birden çok kapsamlı bağımlılıkla çalışmanın bir yolu var mı? ?Örneğin, herbiri bir @Singleton kapsamı Bileşeni olan birden çok kitaplığa sahibim ve tekil örneklerini ActivityComponent ile paylaşabilmeyi istiyorum. Kütüphaneler bağımsız ve birbirlerini görmüyorlar. –