Dagger 2 循环注射
Dagger 2 cycle injection
我有两个单例 class 我想将它们注入到 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);
}
}
我在应用程序 class 中构建了一次图表。
这是错误:
FATAL EXCEPTION: main
java.lang.WhosebugError
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)
首先,这...
@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);
}
希望这对您有所帮助。
我有两个单例 class 我想将它们注入到 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);
}
}
我在应用程序 class 中构建了一次图表。 这是错误:
FATAL EXCEPTION: main java.lang.WhosebugError 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)
首先,这...
@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);
}
希望这对您有所帮助。