2017-08-02 123 views
0

使用匕首2.11,以下代码返回 “错误:[dagger.android.AndroidInjector.inject(T)]找到一个依赖循环:”。这是因为provideApp方法具有参数“App应用程序”。如果我删除它并执行直接提供应用程序实例的肮脏的黑客攻击,代码将编译并运行。匕首2.11依赖循环

从我以前见过的例子,它使用的是常见的做法,以保持模块中的应用程序的实例,并使用其他供应商,但由于该模块类是现在的抽象,这是行不通的@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是一个抽象类,应用程序如果我使用不带静态关键字的@Provides Authenticator provideAuthenticator(),则不会编译。如果我使用static关键字,那么我无法访问非静态应用程序字段。

+0

'应用provideApp(应用程序)' - > ...所以你需要一个'App'提供一个'App'?这是一个错字,或者你没有想到通过 –

+0

编辑我原来的帖子@DavidMedenjak –

回答

2

您的代码:

@Provides 
@Singleton 
static App provideApp(App app) { 
    return app; 
} 

的意思是 “提供应用程序使用App作为一个依赖”。换句话说,你想提供App,但你首先需要App。因此你的周期。

解决这个问题的最好的解决办法是遵循德米特的规则,而不是在所有提供Application单。

为什么你AuthenticatorImpl需要知道具体类型的Application子类的?我敢打赌,你可以重构该类,以使Application不再是它的直接依赖 - 也许你只需要一个上下文。如果您只需要在应用程序范围内使用单身人士,则只需使用@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); 
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每个模块中使用。