Dagger 2 alt bileşenleri ve bileşen bağımlılıkları


135

Dagger 1'in plus()yöntemi önceki uygulamalarda oldukça sık kullandığım bir şeydir, bu yüzden üst grafik bağlantılarına tam erişime sahip bir alt bileşene sahip olmak isteyebileceğiniz durumları anlıyorum.

Hangi durumda, alt bileşen bağımlılığı yerine bileşen bağımlılığı kullanmak yararlı olur ve neden?

Yanıtlar:


228

Bileşen bağımlılıkları - İki bileşeni bağımsız tutmak istediğinizde bunu kullanın.

Alt bileşenler - İki bileşeni bir arada tutmak istediğinizde bunu kullanın.


Bileşen bağımlılıklarını ve Alt bileşenleri açıklamak için aşağıdaki örneği kullanacağım . Örnek hakkında dikkate değer bazı noktalar:

  • SomeClassA1herhangi bir bağımlılık olmadan oluşturulabilir. yöntem aracılığıyla ModuleAsağlar ve örneği .SomeClassA1provideSomeClassA1()
  • SomeClassB1olmadan yaratılamaz SomeClassA1. ModuleBbir örneğini sağlayabilir SomeClassB1bir örneği sadece SomeClassA1bir bağımsız değişken olarak geçirilir provideSomeClassB1()yöntem.
@Module
public class ModuleA {
    @Provides
    public SomeClassA1 provideSomeClassA1() {
        return new SomeClassA1();
    }
}

@Module
public class ModuleB {
    @Provides
    public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {
        return new SomeClassB1(someClassA1);
    }
}

public class SomeClassA1 {
    public SomeClassA1() {}
}

public class SomeClassB1 {
    private SomeClassA1 someClassA1;

    public SomeClassB1(SomeClassA1 someClassA1) {
        this.someClassA1 = someClassA1;
    }
}

Hançer , Bileşen / Alt Bileşen bildirimi her başlatıldığında yönteme SomeClassA1bir argüman olarak geçmeye özen gösterir . Dagger'a bağımlılığı nasıl yerine getireceğini öğretmeliyiz. Bu, Bileşen bağımlılığı veya Alt Bileşen kullanılarak yapılabilir .provideSomeClassB1()ModuleBModuleB

Bileşen bağımlılığı

Aşağıdaki Bileşen bağımlılığı örneğinde aşağıdaki noktalara dikkat edin:

  • ComponentBek açıklama dependenciesyöntemiyle bağımlılığı tanımlamak zorundadır @Component.
  • ComponentAbeyan etmeye gerek yok ModuleB. Bu, iki bileşeni bağımsız tutar.
public class ComponentDependency {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        SomeClassA1 someClassA1();
    }

    @Component(modules = ModuleB.class, dependencies = ComponentA.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }

    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerComponentDependency_ComponentA.builder()
                .moduleA(moduleA)
                .build();

        ModuleB moduleB = new ModuleB();
        ComponentB componentB = DaggerComponentDependency_ComponentB.builder()
                .moduleB(moduleB)
                .componentA(componentA)
                .build();
    }
}

alt bileşen

Alt Bileşen örneğinde aşağıdaki noktalara dikkat edin:

  • ComponentBBağımlılığı tanımlayamadığı gibi , ModuleAbağımsız olarak yaşayamaz. Sağlayacak bileşene bağımlı hale gelir ModuleA. Dolayısıyla bir @Subcomponentek açıklaması vardır.
  • ComponentAModuleBarayüz yöntemi ile beyan etti componentB(). Bu, iki bileşeni birleştirir. Aslında, ComponentBsadece üzerinden başlatılabilir ComponentA.
public class SubComponent {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        ComponentB componentB(ModuleB moduleB);
    }

    @Subcomponent(modules = ModuleB.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }

    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerSubComponent_ComponentA.builder()
                .moduleA(moduleA)
                .build();

        ModuleB moduleB = new ModuleB();
        ComponentB componentB = componentA.componentB(moduleB);
    }
}

4
Daha sonra componentA oluşturucu modülB gerekmez anlamına gelir Bileşen A için Modül B eklemeyen bir alt bileşen kurulum var. Bu, uygulama başlangıcında ComponentA oluşturulmasına izin vermeyi ve ardından m'yi başlatırken beklediğim gibi çalışıyor gibi görünüyor
FriendlyMikhail

2
@MikeN - ComponentA'da ModuleB'den nasıl kurtulacağınızı vurgulayabilir misiniz? Bileşen A'daki Modül B'den yalnızca Bileşen A ve Bileşen B'de farklı kapsamlar sağladığımda kurtulabilirim.
Praveer Gupta

1
Haklısın kurulumum çalışıyor çünkü farklı kapsamlardalar. özürlerimi.
FriendlyMikhail

2
" SomeClassB1bağımlı SomeClassA1. ComponentAaçıkça bağımlılığı tanımlamak zorunda." ==> " ComponentBaçıkça bağımlılığı tanımlamak zorunda" mı demek istediniz?
Tar

1
@Tar'ın işaret ettiğine benzer şekilde, " SomeClassB1bağımlı SomeClassA1. ComponentAAçık bir şekilde bağımlılığı tanımlaması gerekmiyor " da anlıyorum . " ComponentBbağımlılığı açıkça tanımlamanız gerekmez " demek istediniz.
Sebas LG

45

Belgelere göre :

Component Dependencyyalnızca bileşen bağımlılıkları aracılığıyla sağlama yöntemi olarak gösterilen bağlara erişim sağlar, yani yalnızca üst öğede bildirilen türlere erişebilirsiniz Component.

SubComponentsize bir erişim sağlar bütün bu size tüm nesnelere erişim onun bildirilen var ie ilan edildiğinde üst öğesinden bağlayıcı grafikte Modules.

Diyelim diyelim ki, sahip olduğunuz bir ApplicationComponentbütün içeren Androidilgili şeyler ( LocationService, Resources, SharedPreference, vs). Ayrıca , API'larla başa çıkmak DataComponentiçin birlikte kalıcılık için işleri yönettiğiniz yere sahip olmak da istersiniz WebService. İçinde eksikliği tek şey DataComponentise Application Contexthangi bulunduğu ApplicationComponent. Bir almak için en basit yolu Contextdan DataComponentbir bağımlılık olacaktı ApplicationComponent. Yalnızca beyan edilen öğelere erişiminiz olduğundan , Contextaçıkça beyan edilmiş olduğunuzdan emin olmanız gerekir ApplicationComponent. Bu durumda, manuel çalışma yoktur, yani Submodulesüst Componentöğede belirtmeniz ve alt modülünüzü aşağıdaki gibi bir üst modüle açıkça eklemeniz gerekmez.

MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!

Şimdi enjekte etmek istediğiniz durumda düşünün WebServicegelen DataComponentve LocationServicegelen ApplicationComponentsenin içine Fragmentkullanarak hangi bağlar @Submodule plusyukarıda özelliği. Buradaki harika şey, bağlandığınız bileşenin ( ApplicationComponent) açığa çıkmasına veya grafiğin tamamına hemen erişebilmenize gerek olmamasıdır .WebServiceLocationService


2
Eğer doğru anlıyorsam, aradığınız bir arayüz yok @Submodule. Bir yazım hatası mı?
İslam Salah

Bunun farkı göstermek için gerçek bir yaşam örneğini nasıl kullandığını seviyorum. Ancak, bu belgeleri okumaktan daha kafa karıştırıcıdır. classesKesin noktayı göstermek için daha az örnek ve daha fazla resme sahip olmak yardımcı olacaktır .
sudocoder

18

Bileşen ve Alt Bileşenin daha iyi anlaşılması için ekran görüntüsüne sahip kod örneği:

Bileşen: resim açıklamasını buraya girin

  1. AppComponent iki bildirim içerir.
  2. AppComponent, App sınıfına başlar.
  3. HomeActivityComponent, AppComponent'e bağlıdır.
  4. DaggerHomeActivityComponent'in başlatılmasında HomeActivity'de, bir kompozisyon olarak AppComponent nesnesini veriyorum.

alt bileşen:

resim açıklamasını buraya girin

  1. AppComponent, Alt Bileşen veya Alt Bileşenler içerir.
  2. AppComponent, App sınıfına başlar.
  3. Alt Bileşen, ParentComponent'i hakkında bir şey bilmiyor. Bu sadece kendi modüllerini ekleyerek kendi bağımlılıklarını sağlar.
  4. HomeActivity'de Üst Bileşenini kullanarak Alt Bileşen enjekte ediyorum.

Ve Resimli Diyagram: resim açıklamasını buraya girin

Kaynak: bağlantı


Alt bileşen AppComponent'i içeriyorsa diyagram daha anlamlı olmaz mı?
Florian Walther

1

Şimdiye kadar tam olarak fark etmediğim başka bir şey:

  • Bir @Subcomponentörneğin tam olarak bir üst bileşeni vardır (ancak farklı bileşenler aynı örneği başlatabilir @Subcomponentve o örneğin üst öğesi olabilir )
  • A @Component, bileşen bağımlılıkları aracılığıyla bildirilen sıfır, bir veya birçok "üst" bileşene sahip olabilir

1
Muhtemelen ikinci durumda '@Component' in ... ebeveyn (ler) e sahip olabileceğini söylemek doğru değildir. Daha ziyade '@Component' in ebeveynleri yoktur, ancak diğerleri bileşen bağımlılıkları yoluyla buna bağımlı olabilir (sadece kullanın).
demaksee

@demaksee Bilmiyorum, bana öyle geliyor ki, bileşen hiyerarşinizi çıkarırsanız, DAG'a girersiniz ve bence bu ilişkiyi grafik bağlamında ebeveyn-çocuk olarak adlandırmanın standart bir yolu. Dagger'ın iç işleyişinden bahsediyorsak, o zaman doğru kelime olmayabilir.
arekolek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.