Saya mencoba untuk membungkus kepala saya di sekitar lingkup di Dagger 2, khususnya siklus hidup dari grafik yang dilingkari. Bagaimana Anda membuat komponen yang akan dibersihkan ketika Anda meninggalkan ruang lingkup.
Dalam hal aplikasi Android, menggunakan Belati 1.x Anda umumnya memiliki ruang lingkup root di tingkat aplikasi yang Anda akan memperluas untuk membuat ruang lingkup anak di tingkat aktivitas.
public class MyActivity {
private ObjectGraph mGraph;
public void onCreate() {
mGraph = ((MyApp) getApplicationContext())
.getObjectGraph()
.plus(new ActivityModule())
.inject(this);
}
public void onDestroy() {
mGraph = null;
}
}
Lingkup anak ada selama Anda menyimpan referensi untuknya, yang dalam hal ini adalah siklus hidup Aktivitas Anda. Menjatuhkan referensi di onDestroy memastikan grafik yang dicakup bebas dari sampah yang dikumpulkan.
EDIT
Jesse Wilson baru-baru ini memposting cula mea
Belati 1.0 benar-benar mengacaukan nama ruang lingkupnya ... Anotasi @Singleton digunakan untuk grafik akar dan grafik khusus, jadi sulit untuk mengetahui apa sebenarnya ruang lingkup suatu benda.
dan segala sesuatu yang telah saya baca / dengar poin menuju Dagger 2 meningkatkan cara kerja lingkup, tapi saya berjuang untuk memahami perbedaannya. Menurut komentar @ Kirill Boyarshinov di bawah ini, siklus hidup komponen atau ketergantungan masih ditentukan, seperti biasa, dengan referensi konkret. Jadi, apakah perbedaan antara cakupan Dagger 1.x dan 2.0 hanya masalah kejelasan semantik?
Pemahaman saya
Belati 1.x
Dependensi ada @Singleton
atau tidak. Ini sama benarnya dengan dependensi dalam grafik root dan subgraf, yang mengarah ke ambiguitas terkait dengan grafik yang mana ketergantungan itu terikat (lihat Dalam Belati adalah Singleton dalam sub-grafik yang di-cache atau akan selalu diciptakan kembali ketika suatu sub-grafik aktivitas baru dibangun? )
Belati 2.0
Lingkup khusus memungkinkan Anda untuk membuat ruang lingkup yang jelas secara semantik, tetapi secara fungsional setara dengan penerapan @Singleton
di Belati 1.x.
// Application level
@Singleton
@Component( modules = MyAppModule.class )
public interface MyAppComponent {
void inject(Application app);
}
@Module
public class MyAppModule {
@Singleton @Named("SingletonScope") @Provides
StringBuilder provideStringBuilderSingletonScope() {
return new StringBuilder("App");
}
}
// Our custom scope
@Scope public @interface PerActivity {}
// Activity level
@PerActivty
@Component(
dependencies = MyAppComponent.class,
modules = MyActivityModule.class
)
public interface MyActivityComponent {
void inject(Activity activity);
}
@Module
public class MyActivityModule {
@PerActivity @Named("ActivityScope") @Provides
StringBuilder provideStringBuilderActivityScope() {
return new StringBuilder("Activity");
}
@Name("Unscoped") @Provides
StringBuilder provideStringBuilderUnscoped() {
return new StringBuilder("Unscoped");
}
}
// Finally, a sample Activity which gets injected
public class MyActivity {
private MyActivityComponent component;
@Inject @Named("AppScope")
StringBuilder appScope
@Inject @Named("ActivityScope")
StringBuilder activityScope1
@Inject @Named("ActivityScope")
StringBuilder activityScope2
@Inject @Named("Unscoped")
StringBuilder unscoped1
@Inject @Named("Unscoped")
StringBuilder unscoped2
public void onCreate() {
component = Dagger_MyActivityComponent.builder()
.myApplicationComponent(App.getComponent())
.build()
.inject(this);
appScope.append(" > Activity")
appScope.build() // output matches "App (> Activity)+"
activityScope1.append("123")
activityScope1.build() // output: "Activity123"
activityScope2.append("456")
activityScope1.build() // output: "Activity123456"
unscoped1.append("123")
unscoped1.build() // output: "Unscoped123"
unscoped2.append("456")
unscoped2.build() // output: "Unscoped456"
}
public void onDestroy() {
component = null;
}
}
Hal yang dapat diambil adalah bahwa penggunaan @PerActivity
mengkomunikasikan niat Anda mengenai siklus hidup komponen ini, tetapi pada akhirnya Anda dapat menggunakan komponen di mana saja / kapan saja. Satu-satunya janji belati adalah bahwa, untuk komponen tertentu, metode yang dijelaskan lingkup akan mengembalikan satu contoh. Saya juga menganggap Dagger 2 menggunakan penjelasan lingkup pada komponen untuk memverifikasi bahwa modul hanya menyediakan dependensi yang berada dalam cakupan yang sama atau non-cakupan.
Singkatnya
Dependensi masih berupa singleton atau non-singleton, tetapi @Singleton
sekarang ditujukan untuk instance singleton level aplikasi dan cakupan kustom adalah metode yang disukai untuk menjelaskan ketergantungan singleton dengan siklus hidup yang lebih pendek.
Pengembang bertanggung jawab untuk mengelola siklus hidup komponen / dependensi dengan menjatuhkan referensi yang tidak lagi diperlukan dan bertanggung jawab untuk memastikan bahwa komponen hanya dibuat satu kali dalam ruang lingkup yang dimaksudkan, tetapi penjelasan ruang lingkup kustom memudahkan untuk mengidentifikasi ruang lingkup itu. .
Pertanyaan $ 64rb *
Apakah pemahaman saya tentang lingkup dan siklus hidup Dagger 2 benar?
* Sebenarnya bukan pertanyaan $ 64'000.
plus()
referensi ke grafik baru disimpan di Activity, dan terikat pada siklus hidupnya (dereferenced inonDestroy
). Adapun cakupan, mereka memastikan implementasi komponen Anda dihasilkan tanpa kesalahan pada waktu kompilasi, dengan setiap ketergantungan terpenuhi. Jadi bukan hanya untuk keperluan dokumentasi. Lihatlah beberapa contoh dari utas ini .