Pertanyaan Bagaimana cara mengatasi ketergantungan melingkar saat masih menggunakan Dagger2?


Saya memiliki dua kelas, Foo<T> dan Bar, yang bergantung satu sama lain, serta berbagai kelas lainnya. Saya menggunakan Dagger-2 untuk injeksi ketergantungan, tetapi jika saya secara naively menambahkan ketergantungan melingkar, Dagger memukul tumpukan overflow saat runtime. Apa cara yang baik untuk refactor kelas untuk memperbaiki ini, sementara masih menggunakan Dagger untuk menyuntikkan semua dependensi lainnya, dan dengan duplikasi minimal dan perubahan pada panggilan yang sudah ada?


7
2018-06-22 21:29


asal


Jawaban:


Jalan keluar yang mudah adalah menggunakan Lazy<T> di satu sisi.

Lazy<Foo> foo;

Bar(Lazy<Foo> foo) {
    this.foo = foo;
}

// use foo.get(); when needed

13
2018-06-22 21:42



Setelah terlalu banyak berpikir dan berbicara dengan rekan kerja, kami akhirnya melakukan hal-hal berikut:

class Foo<T> extends FooWithoutDep<T> {
    @Inject Foo(Bar bar, OtherDep1 dep1, OtherDep2 dep2) {
        super(dep1, dep2);
        setBarDep(bar);
    }
}

class FooWithoutDep<T> {
    //Field declarations elided
    @Inject FooWithoutDep(OtherDep1 dep1, OtherDep2 dep2) {
        //Normal constructor stuff
    }
    void setBarDep(Bar bar) { this.bar = bar; }

    //The rest of the actual logic
}

class Bar {
    //Field declarations elided
    @Inject Bar(FooWithoutDep<Thing> foo, OtherDep3 dep3) {
        this.foo = foo;
        this.foo.setBarDep(this);
        this.dep3 = dep3;
    }

    //Code that uses Foo and the other dependencies
}

Menjelaskan hal ini - kami memindahkan logika Foo yang sebenarnya ke dalam kelas induk (FooWithoutDep), yang mengambil ketergantungan melingkar sebagai bidang yang dapat diatur dan bukan parameter konstruktor. Kemudian kelas asli hanya berisi konstruktor yang mengambil ketergantungan lingkaran dan memanggil setter. Kelas lain, Bar, tergantung pada orang tua (FooWithoutDep), dan memanggil setter secara eksplisit, melewati dirinya sendiri (this). Ini memungkinkan semua referensi yang ada ke kelas tetap sama, sementara masih menggunakan Dagger untuk menyuntikkan semua dependensi.

Ini tampaknya cukup membingungkan untuk ditulis di sini.


2
2018-06-22 21:29



Ini adalah bagaimana saya menyelesaikannya, tanpa kelas orang tua.

Kelas 1: Mesin. (dalam antarmuka komponen)     @Menyediakan     Mesin publik myEngine (Konteks konteks) {         mengembalikan Mesin baru (konteks);     }

Kelas 2: Bagian. Engine juga membutuhkan instance Bagian tetapi kreasi tertunda.

@Inject
public Parts(Context context, Engine engine) {
    this.context = context;
    this.engine= engine;
    engine.setParts(this);
}

Ketergantungan lingkaran dapat dicapai tetapi satu kelas harus dimulai terlebih dahulu sebelum yang lain.

Sekali lagi, jika mungkin, kode refactor untuk menghindari DI melingkar.


0
2017-08-16 03:15