2017-12-07 1 views
0

Ich habe folgende Module:Wie vermeidet man eine zirkuläre Abhängigkeit mit Dolch 2?

@Module 
class HomeModule(private val context: Context) { 

    @Provides 
    fun provideContext() = context 

    @Provides 
    fun provideHomeUi(): HomeUi { 
     return HomeUi() 
    } 

    @Provides 
    @Singleton 
    fun provideHomePresenter(homeUi: HomeUi): HomePresenter { 
     return HomePresenter(homeUi) 
    } 
} 

Diese injizierten Felder in HomeUi.kt

@Inject lateinit var context: Context 
@Inject lateinit var presenter: HomePresenter 

und dieses in HomePresenter.kt

@Inject lateinit var context: Context 

Hier Komponente meine Deps

@Singleton 
@Component(modules = arrayOf(
     NetworkModule::class, 
     HomeModule::class 
)) 
interface Deps { 
    fun inject(homePresenter: HomePresenter) 
    fun inject(homeActivity: HomeActivity) 
    fun inject(homeUi: HomeUi) 
} 

ich verwende Dagger 2.10 aber ein StackOverflowError ausgelöst. Ich suche nach einer Möglichkeit, meine zirkuläre Abhängigkeit zu vermeiden.

Hinweis: Dies ist mein HomeUi die unendlich instanziiert wird.

Antwort

1

Es scheint so, als würden Sie die Feldinjektion über HomeUi von Ihrem Presenterkonstruktor aus aufrufen, wodurch eine Endlosschleife ausgelöst wird, da kein Objekt ohne das andere (?) Fertiggestellt werden kann. Das sieht nach einem wirklich schlechten Ansatz aus und Sie sollten versuchen, Ihre Abhängigkeiten in die Objektkonstruktoren zu verschieben, anstatt halbfertige Objekte zu erstellen.

Verwenden Feldeinkopplung vor allem für Objekte, die Sie nicht selbst erstellen können, zum Beispiel mit Android-Framework-Typen. IMHO inject(homeActivity: HomeActivity) sollte die einzige Methode Ihrer Komponente sein.

Zyklische Abhängigkeiten sind schwer zu verwalten, und es gibt keine perfekte Lösung, aber Sie können Dinge versuchen, wie zum Beispiel Provider<HomePresenter> wechseln, um die Abhängigkeit zu verzögern und in der Lage sein, es auf diese Weise zu lösen.

Folgendes sollte das tun, was Sie bestimmt, und es beachten, wie ich Konstruktor Injektion bin mit, anstelle von 2 zusätzlichen Methoden im Modul.

@Singleton 
@Component(modules = arrayOf(
    NetworkModule::class, 
    HomeModule::class 
)) 
interface Deps { 
    fun inject(homeActivity: HomeActivity) 
} 

@Module 
class HomeModule(private val context: Context) { 

    @Provides 
    fun provideContext() = context 

} 

@Singleton 
class HomeUi @Inject constructor(presenter : Provider<HomePresenter>, context : Context) 
{ 
    // use with presenter.get() 
} 

@Singleton 
class HomePresenter @Inject constructor(homeUi : HomeUi) 

Bitte beachten Sie, dass ein Provider<T> mit dem billigsten Weg ist, eine zyklische Abhängigkeit, die ich kenne, aber es könnte nicht für jede Situation zu lösen geeignet sein.

+0

Ich habe Ihren Ansatz gefolgt von injizieren mit() nur für Objekte, die ich nicht schaffen kann, und es sieht in der Tat besser. Danke für Ihre Ratschläge! –

1

Ich habe selber nie Dagger 2 mit Kotlin aber ich benutze es in Java. Ich erstelle normalerweise mein Modul mit meiner Sicht als param und meine Methode provideHomeUi() gibt meine Ansicht als Parameter zurück. Damit sollten Sie keinen StackOverflowError haben.

Btw, warum verwenden Sie Dagger 2 mit Kotlin und nicht direkt Bibliothek für DI auf Kotlin, wie kodein, Koin etc ...

Viel Glück.

Verwandte Themen