使用Dagger 2.11,以下代码返回“错误:[dagger.android.AndroidInjector.inject(T)]找到一个依赖循环:”。发生这种情况是因为provideApp方法具有参数“App app”。如果我删除它并执行直接提供应用程序实例的脏黑客,则代码将编译并运行。
从我以前见过的例子中,过去常常将应用程序的实例保存在模块中并将其用于其他提供程序,但由于此模块类现在是抽象的,因此不能用作@Provide方法需要是静态的。
我该如何解决这个问题?
@Module(includes = AndroidInjectionModule.class)
public abstract class AppModule {
@Provides
@Singleton
static App provideApp(App app) {
return app;
}
@Provides
static Authenticator provideAuthenticator(App app) {
return new AuthenticatorImpl(app);
}
}
修改
我需要实现的基本上是这种行为:
@Module(includes = AndroidInjectionModule.class)
public class AppModule {
private App application;
AppModule(App app) {
application = app;
}
@Provides
Authenticator provideAuthenticator() {
return new AuthenticatorImpl(application);
}
}
但是,这不起作用,因为AppModule现在是一个抽象类,如果我使用没有static关键字的@Provides Authenticator provideAuthenticator(),app将无法编译。如果我使用static关键字,那么我无法访问非静态应用程序字段。
答案 0 :(得分:3)
您的代码:
@Provides
@Singleton
static App provideApp(App app) {
return app;
}
表示"使用App作为依赖关系提供App"。换句话说,您希望提供App
,但首先需要App
。因此你的周期。
此问题的最佳解决方案是遵循Demeter规则,而不是提供Application
单例。
为什么您的AuthenticatorImpl
需要知道Application
子类的具体类型?我打赌你可以重构那个类,以便Application
不再是它的直接依赖 - 也许你只需要一个Context。如果您只需要在应用程序范围内使用单例,则可以使用@Singleton
@Provides
方法创建一个模块,并将其安装在应用程序组件中。
如果在此之后,您发现必须@Provide
您的子类,则可以创建一个不包含任何其他模块的新模块:
@Module //don't include other modules here
class AppModule {
private final App app;
public AppModule(App app) {
this.app = app;
}
@Provides
@Singleton
App app() {
return app;
}
}
并将其安装在您的应用级组件中:
//inside your App class
DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build()
.inject(this);
答案 1 :(得分:0)
如果您在Application
中实施了以下内容,则不需要AppModule:
public class App extends DaggerApplication {
private AndroidInjector<App> appInjector;
@dagger.Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class
})
public interface Component extends AndroidInjector<App> {
@dagger.Component.Builder
abstract class Builder extends AndroidInjector.Builder<App> {}
}
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerApp_Component
.builder()
.username("Username from application")
.create(this);
}
}
现在App
将依赖于全局范围,并且可以在链接到@Component
的每个模块中使用。