Belati 2 subkomponen vs ketergantungan komponen

135

plus()Metode Dagger 1 adalah sesuatu yang saya gunakan cukup sering dalam aplikasi sebelumnya, jadi saya memahami situasi di mana Anda mungkin ingin memiliki subkomponen dengan akses penuh ke binding grafik induk.

Dalam situasi apa akan bermanfaat untuk menggunakan ketergantungan komponen daripada ketergantungan subkomponen dan mengapa?

Bradley Campbell
sumber

Jawaban:

228

Ketergantungan komponen - Gunakan ini saat Anda ingin menjaga dua komponen tetap independen.

Subkomponen - Gunakan ini saat Anda ingin tetap menyatukan dua komponen.


Saya akan menggunakan contoh di bawah ini untuk menjelaskan dependensi dan Subkomponen Komponen . Beberapa poin yang perlu diperhatikan tentang contoh ini adalah:

  • SomeClassA1dapat dibuat tanpa ketergantungan. ModuleAmenyediakan dan contoh SomeClassA1melalui provideSomeClassA1()metode ini.
  • SomeClassB1tidak dapat dibuat tanpa SomeClassA1. ModuleBdapat memberikan instance SomeClassB1hanya jika instance SomeClassA1dilewatkan sebagai argumen ke provideSomeClassB1()metode.
@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;
    }
}

Belati akan mengurus lewat instance SomeClassA1sebagai argumen untuk provideSomeClassB1()metode pada ModuleBsetiap kali Komponen / Subkomponen menyatakan mendeklarasikan ModuleBdiinisialisasi. Kita perlu menginstruksikan Belati bagaimana memenuhi ketergantungan. Ini dapat dilakukan dengan menggunakan ketergantungan Komponen atau Subkomponen .

Ketergantungan komponen

Perhatikan poin-poin berikut dalam contoh ketergantungan Komponen di bawah ini:

  • ComponentBharus mendefinisikan ketergantungan melalui dependenciesmetode pada @Componentanotasi.
  • ComponentAtidak perlu mendeklarasikan ModuleB. Ini menjaga dua komponen independen.
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();
    }
}

Subkomponen

Perhatikan poin-poin berikut dalam contoh SubComponent:

  • Karena ComponentBbelum mendefinisikan ketergantungan ModuleA, ia tidak dapat hidup mandiri. Itu menjadi tergantung pada komponen yang akan menyediakan ModuleA. Karenanya ia memiliki @Subcomponentanotasi.
  • ComponentAtelah dideklarasikan ModuleBmelalui metode antarmuka componentB(). Ini membuat kedua komponen tersebut berpasangan. Bahkan, ComponentBhanya dapat diinisialisasi melalui 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);
    }
}
Praveer Gupta
sumber
4
Saya memiliki pengaturan subkomponen yang tidak menambahkan Modul B ke ComponentA, yang kemudian berarti bahwa pembangun componentA tidak memerlukan moduleB. Ini sepertinya bekerja dengan cara yang saya harapkan memungkinkan pembuatan ComponentA pada awal aplikasi dan kemudian instantiating m
FriendlyMikhail
2
@ MikeN - Bisakah Anda menyoroti bagaimana Anda bisa menghilangkan ModuleB pada ComponentA? Saya dapat menyingkirkan ModuleB pada ComponentA hanya jika saya menyediakan cakupan yang berbeda pada ComponentA dan ComponentB.
Praveer Gupta
1
Anda benar pengaturan saya berfungsi karena mereka berada di ruang lingkup yang berbeda. permintaan maaf.
FriendlyMikhail
2
" SomeClassB1Tergantung pada SomeClassA1. ComponentAharus secara eksplisit menentukan ketergantungan." ==> Sudahkah Anda bermaksud " ComponentBharus secara eksplisit mendefinisikan ketergantungan"?
Tar
1
Demikian pula dengan apa yang ditunjukkan @Tar, saya mengerti bahwa " SomeClassB1tergantung pada SomeClassA1. Tidak ComponentAperlu mendefinisikan ketergantungan secara eksplisit." Anda berarti " ComponentBtidak perlu mendefinisikan ketergantungan secara eksplisit."
Sebas LG
45

Menurut dokumentasi :

Component Dependencymemberi Anda akses hanya ke bindings yang diekspos sebagai metode penyediaan melalui dependensi komponen, yaitu Anda memiliki akses ke hanya tipe yang dideklarasikan di induk Component.

SubComponentmemberi Anda akses ke seluruh grafik yang mengikat dari induknya ketika dideklarasikan, yaitu Anda memiliki akses ke semua objek yang dideklarasikan dalam Modules.

Mari mengatakan, Anda memiliki ApplicationComponentyang berisi semua Androidhal yang terkait ( LocationService, Resources, SharedPreference, dll). Anda juga ingin memiliki DataComponenttempat Anda mengelola hal-hal untuk kegigihan bersama WebServiceuntuk berurusan dengan API. Satu-satunya kekurangan Anda DataComponentadalah Application Contextyang tinggal ApplicationComponent. Cara paling sederhana untuk mendapatkan Contextdari DataComponentakan menjadi ketergantungan ApplicationComponent. Anda harus memastikan bahwa Anda telah Contextmendeklarasikan secara eksplisit ApplicationComponentkarena Anda hanya memiliki akses ke hal-hal yang dinyatakan. Dalam hal ini, tidak ada pekerjaan manual, yang berarti Anda tidak perlu menentukan Submodulesdalam induk Componentdan secara eksplisit menambahkan submodule Anda ke modul induk seperti:

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

Sekarang pertimbangkan kasus di mana Anda ingin menyuntikkan WebServicedari DataComponentdan LocationServicedari ApplicationComponentAnda Fragmentyang mengikat menggunakan @Submodule plusfitur di atas. Yang keren di sini adalah bahwa komponen yang Anda ikat ( ApplicationComponent) tidak perlu dibuka WebServiceatau LocationServicekarena Anda memiliki akses ke seluruh grafik segera.

Eugene
sumber
2
Jika saya mengerti benar, tidak ada antarmuka yang disebut @Submodule. Apakah ini salah ketik?
Islam Salah
Saya suka bagaimana ini menggunakan contoh kehidupan nyata untuk menunjukkan perbedaannya. Namun, ini lebih membingungkan daripada membaca dokumen. Ini akan membantu untuk memiliki lebih sedikit classessebagai contoh dan lebih banyak gambar untuk menggambarkan titik yang tepat.
sudocoder
18

Berikut ini contoh kode dengan tangkapan layar untuk lebih memahami Komponen dan Subkomponen:

Komponen: masukkan deskripsi gambar di sini

  1. AppComponent berisi dua deklarasi.
  2. AppComponent diinisialisasi ke dalam kelas Aplikasi.
  3. HomeActivityComponent bergantung pada AppComponent.
  4. Dalam HomeActivity tentang inisialisasi DaggerHomeActivityComponent, saya memberikan objek AppComponent sebagai komposisi.

Subkomponen:

masukkan deskripsi gambar di sini

  1. AppComponent berisi SubComponent atau SubComponents.
  2. AppComponent diinisialisasi ke dalam kelas Aplikasi.
  3. SubComponent tidak tahu tentang ParentComponentnya. Itu hanya menyediakan dependensinya sendiri dengan memasukkan Modul.
  4. Dalam HomeActivity saya menyuntikkan SubComponent dengan menggunakan Komponen Induknya.

Dan Diagram Pictorial: masukkan deskripsi gambar di sini

Sumber: tautan

0xAliHn
sumber
Bukankah diagram akan lebih masuk akal jika subkomponen menyertakan AppComponent?
Florian Walther
1

Satu hal lain yang saya tidak sadari sampai sekarang adalah:

  • Sebuah @Subcomponentinstance memiliki tepat satu komponen induk (walaupun komponen yang berbeda dapat membuat instance yang sama @Subcomponentdan menjadi induk instance itu)
  • A @Componentmungkin memiliki nol, satu, atau banyak komponen "induk" yang dideklarasikan melalui dependensi komponen
arekolek
sumber
1
Mungkin dalam kasus kedua tidak benar untuk mengatakan '@Component' mungkin memiliki ... parent (s). Sebaliknya '@Component' tidak memiliki orang tua, tetapi yang lain mungkin bergantung pada itu (cukup menggunakannya) melalui dependensi komponen.
demaksee
@ demaksee Saya tidak tahu, menurut saya jika Anda memetakan hierarki komponen Anda, Anda akan dapatkan di DAG, dan saya pikir itu adalah cara standar untuk menyebut hubungan ini sebagai orang tua-anak dalam konteks grafik. Jika kita berbicara tentang cara kerja belati, maka kurasa itu mungkin bukan kata yang tepat.
arekolek