Dagger Module Inclusion Cycle
android, dagger
Solution
`addsTo=` is there to specify that this graph is an extension to the referenced module in a parent/child graph. .plus() is the run-time version of this. You only need .plus() if you have shorter-lived graph-managed instances. This corresponds roughly to the notion of "scope" in Guice and other DI containers.
In your example you are doing:
applicationGraph = ObjectGraph
.create(new MyAppModule())
.plus(new AnalyticsModule());
This ends up creating two graphs in a parent/child relationship, which isn't what you need here. IN an android app you want one graph for the Application.
You can simply remove addsTo and MyAppModule will automatically instantiate AnalyticsModule, or you can pass both in if you want to avoid the dynamic initialization like so:
applicationGraph = ObjectGraph.create(new MyAppModule(), new AnalyticsModule());
The module inclusion cycle is because you have a cyclical relationship between these two modules and modules must themselves form an acyclic graph of configuration. MyAppModule includes AnalyticsModule which in turn includes MyAppModule. (addsTo is a less rigorous includes= used to specify things obtained from parent graphs)
Problem
I'm still new to Dagger and trying to get a hang of things. I wanted to split my modules into logical groups which each provide their own functionality, yet basically would act the same as if it were in one Module. For instance, let's say I have my main application module defined as follows: ``` //com.example.android.MyAppModule.java @Module( includes = AnalyticsModule.class, injects = { <snip> } ) public class MyAppModule { // various provides } ``` And I have another module defined like this which sets up an ErrorReporter interface and provides the concrete implementation to it. ``` // com.example.android.analytics.AnalyticsModule.java @Module( addsTo = MyAppModule.class, injects = { MyApp.class } ) public class AnalyticsModule(){ // ErrorReporter is a public interface and ErrorReporterImpl is a package-local final concrete class that implements it @Provides @Singleton ErrorReporter providesErrorReporter(ErrorReporterImpl reporter) { return reporter }; } ``` In my Application class I set up the object graph like this: ``` // com.example.android.MyApp.java public class MyApp extends Application { @Inject ErrorReporter errorReporter; @Override public void onCreate() { super.onCreate(); applicationGraph = ObjectGraph .create(new MyAppModule()) .plus(new AnalyticsModule()); applicationGraph.inject(this); errorReporter.initialize(); } } ``` When I run the dagger compiler I get something like this: ``` Graph validation failed: Module Inclusion Cycle: 0. com.example.android.analytics.AnalyticsModule included by com.example.android.MyAppModule 1. com.example.android.modules.MyAppModule included by com.example.android.analytics.AnalyticsModule 0. com.example.android.analytics.AnalyticsModule ``` What am I doing wrong here? I assume it has something to do with includes/addsTo, but when I remove those I get other errors. If I remove includes = AnalyticsModule.class from MyAppModule I get something like this: ``` com.example.android.analytics.ErrorReporter could not be bound with key com.example.android.analytics.ErrorReporter required by com.example.android.MyApp for com.example.android.MyAppModule ``` Everything is fine if I completely forgo an AnalyticsModule and then hand off the providesErrorReporter to MyAppModule, but then I have to make my concrete impl class public so I can use it in the other module.