2017-12-07 63 views
0

私は、次のモジュールがあります:HomeUi.ktDagger 2で循環依存を避けるにはどうすればよいですか?

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

@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) 
    } 
} 

これらの注入されたフィールドとここでHomePresenter.kt

@Inject lateinit var context: Context 

私のDEPのコンポーネントで、このいずれかを

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

Dagger 2.10を使用していますが、StackOverflowErrorがスローされます。私は私の循環依存を避ける方法を探しています。

注:これは無限にインスタンス化している私のHomeUiです。

答えて

1

HomeUiのフィールド注入を発表者のコンストラクタ内から呼び出すように見えるので、どちらのオブジェクトも他のもの(?)なしで構築できないため、無限ループが発生します。これは本当に悪いアプローチのように見えます。半完成のオブジェクトを作成するのではなく、依存関係をオブジェクトコンストラクタに移動してください。

フィールド注入は、自分では作成できないオブジェクト(例: Androidフレームワークタイプを使用します。 IMHO inject(homeActivity: HomeActivity)は、コンポーネントの唯一の方法である必要があります。

サイクリック依存関係は管理が難しく、完璧な解決策はありませんが、Provider<HomePresenter>に切り替えるなどして依存関係を遅延させ、このように解決できるようにすることができます。

以下は、あなたが意図した通りに動作するはずです。モジュールに2つのメソッドを追加する代わりに、コンストラクタインジェクションをどのように使用しているかに注意してください。

@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) 

Provider<T>を使用して、私が知っている循環依存を解決するための最も安い方法ですが、それはすべての状況に適していない可能性がありますのでご注意ください。

+0

私はあなたが作成できないオブジェクトに対してのみinject()を使用することであなたのアプローチに従いました。あなたのアドバイスをありがとう! –

1

私はkotlinでDagger 2を使用したことはありませんでしたが、私はそれをjavaで使用します。私は通常、自分のビューをparamとして作成し、私のメソッドprovideHomeUi()は自分のビューをパラメータとして返します。これであなたはStackOverflowErrorを持ってはいけません。

ところで、なぜあなたは、このようなKodein、光陰等...

幸運として、KotlinのDIのための直接のライブラリKotlinとダガー2を使用していません。

関連する問題