0

私は2つのシングルトンクラスを持っていますが、これらをFragments、Activitesなどに挿入したいのですが、私はそれらもお互いに注入する必要があります。 そしてその時点で私はいつもSOエラーになる。ダガー2サイクルインジェクション

public class AdverticumChecker implements IAdverticumChecker { 

    @Inject BannerManager bannerManager; 

    public AdverticumChecker(Context context) { 
     IndexApplication.getApplication().getAppComponent().inject(this); 
    } 
} 

public class BannerManager { 
    @Inject IAdverticumChecker adverticumChecker; 

    public BannerManager(){ 
     IndexApplication.getApplication().getAppComponent().inject(this); 
    } 
} 

これらは、私はApplicationクラスで一度グラフを構築するモジュール

@Module 
public class BannerManagerModule { 

     @Singleton 
     @Provides 
     BannerManager provideBannerManager(){ 
      return new BannerManager(); 
     } 
    } 

@Module 
public class AdverticumCheckerModule { 
    private Context context; 

    public AdverticumCheckerModule(Context context){ 
     this.context = context; 
    } 

    @Singleton 
    @Provides 
    IAdverticumChecker provideAdverticumChecker(){ 
     return new AdverticumChecker(context); 
    } 
} 

です。

FATAL EXCEPTION: main java.lang.StackOverflowError at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:38) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679) at com.aff.index.adverticum.AdverticumChecker.(AdverticumChecker.java:50) at com.aff.index.dagger.AdverticumCheckerModule.provideAdverticumChecker(AdverticumCheckerModule.java:30) at com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:24) at com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:8) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:67) at com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:11) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:704) at com.aff.index.adverticum.BannerManager.(BannerManager.java:89) at com.aff.index.dagger.BannerManagerModule.provideBannerManager(BannerManagerModule.java:21) at com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:24) at com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:8) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:39) at com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8) at com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679)

答えて

0

まず物事まず、この...

@Singleton 
@Provides 
IAdverticumChecker provideAdverticumChecker(){ 
    return new AdverticumChecker(context); 
} 
... 
public AdverticumChecker(Context context) { 
    IndexApplication.getApplication().getAppComponent().inject(this); 
} 

は基本的にはむしろあなたのコンストラクタで、いくつかの静的なアクセサがそれらを注入させるよりも、依存関係を注入し、DIは何の略か回避: そして、ここではエラーがあります魔法のように - この方法AdvertiumCheckerはほとんどテストすることが不可能です!代わりにコンストラクタの引数として、すべての依存関係を一覧表示し、このようにそれを実行します。

@Singleton 
@Provides 
IAdverticumChecker provideAdverticumChecker(BannerManager bannerManager){ 
    return new AdverticumChecker(bannerManager); 
} 
... 
private BannerManager mBannerManager; 
public AdverticumChecker(BannerManager bannerManager) { 
    mBannerManager = bannerManager; 
} 

ダガーは自動的にここにあなたのためのギャップを埋め、適切なグラフを構築します。

第2に、BannerManagerの構成がIAdvertiumCheckerのインスタンスに依存する場合、Daggerが間違ってしまう循環依存性があることは明らかです。通常、これは悪いデザインのようなにおいがしますが、実行時に何かが必要な場合に備えて、時々違うことができません。これらのケースでは

Lazy注射での作業、すなわち、いずれかの

@Inject 
Lazy<BannerManager> mLazyBannerManager; 
... 
mLazyBannerManager.get().doSomething(); 

または

IAdvertiumChecker providerAdvertiumChecker(Lazy<BannerManager> lazyBannerManager) { 
    return new AdverticumChecker(lazyBannerManager); 
} 

・ホープ、このことができます。

+0

ありがとう、argsのトラフコンストラクタを渡すと、怠け者の注射を使用して私のように動作します。しかし、今私はちょっと混乱しています。コンストラクタでargを渡さなければならないときと、@Injectを使用して依存関係を注入するときを決定するにはどうすればよいですか? – user3057944

+0

インターフェイスを使って実装を隠すことができない場合は、クラスのコンストラクタに '@ Inject'と注釈を付けるだけで、Dagger2はこのコンストラクタを使用してクラスを作成します。そのようなコンストラクタでは、すべての引数を自分自身で追加(バインド)するか(@Iject public Foo(Bar bar、Baz baz);)、空のコンストラクタを使用して、注入可能なメンバに '@Inject '。 –

+0

ありがとう、私は今あなたの助けを借りて行くことができます。とにかく、私はこの時点でもう一つ質問があります。私は私のアプリでsingletoneクラスを使用し、これらのカルセで同期メソッドを使用しました。しかし、私はダガーにシングルトンを作成させるので、私のメソッドがシンクロナイズされれば、彼らは仕事を終了させます。しかし、私は同期キーワードを削除すると、仕事。私は短剣でシングルトンを作成する場合、シンクロトーンクラスで同期メソッドを使用してはいけませんか? – user3057944

関連する問題