Dagger 2循环注射

时间:2016-09-22 15:12:17

标签: java android dependency-injection stack-overflow dagger-2

我有两个单音类我想将它们注入Fragments,Activites等,但我也要将它们注入彼此。 在那一点上,我总是得到SO错误。

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

这些是模块

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

我在Application类中构建了一次图。 这是错误:

  

致命的例外:主要                                                                             java.lang.StackOverflowError的                                                                                 在   com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:38)                                                                                 在   com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8)                                                                                 在   com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679)                                                                                 在   com.aff.index.adverticum.AdverticumChecker。(AdverticumChecker.java:50)                                                                                 在   com.aff.index.dagger.AdverticumCheckerModule.provideAdverticumChecker(AdverticumCheckerModule.java:30)                                                                                 在   com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:24)                                                                                 在   com.aff.index.dagger.AdverticumCheckerModule_ProvideAdverticumCheckerFactory.get(AdverticumCheckerModule_ProvideAdverticumCheckerFactory.java:8)                                                                                 在dagger.internal.DoubleCheck.get(DoubleCheck.java:46)                                                                                 在   com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:67)                                                                                 在   com.aff.index.adverticum.BannerManager_MembersInjector.injectMembers(BannerManager_MembersInjector.java:11)                                                                                 在   com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:704)                                                                                 在   com.aff.index.adverticum.BannerManager。(BannerManager.java:89)                                                                                 在   com.aff.index.dagger.BannerManagerModule.provideBannerManager(BannerManagerModule.java:21)                                                                                 在   com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:24)                                                                                 在   com.aff.index.dagger.BannerManagerModule_ProvideBannerManagerFactory.get(BannerManagerModule_ProvideBannerManagerFactory.java:8)                                                                                 在dagger.internal.DoubleCheck.get(DoubleCheck.java:46)                                                                                 在   com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:39)                                                                                 在   com.aff.index.adverticum.AdverticumChecker_MembersInjector.injectMembers(AdverticumChecker_MembersInjector.java:8)                                                                                 在   com.aff.index.dagger.DaggerAppComponent.inject(DaggerAppComponent.java:679)

1 个答案:

答案 0 :(得分:1)

首先,这是......

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

Dagger会在这里为你自动填补空白并构建一个合适的图表。

其次,如果BannerManager的构造依赖于IAdvertiumChecker的实例,那么你显然会有一个Dagger错误的循环依赖关系。通常这有点像糟糕的设计,但有时它不可能有所不同,以防你在运行时需要一些东西。

在这些情况下,使用Lazy注射,即

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

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

希望这有帮助。