3

Is it possible to have Dagger inject singletons for you?

As things stand, I've only found a way to manually provide dependencies to singletons:

@Provides
@Singleton
public Dispatcher providesDispatcher(Context context, PPreferences preferences,
                                                       FileNameCache fileNameCache) {
    return new Dispatcher(context, preferences, fileNameCache);
}

Is this the only way to define singletons? What I'd prefer to do is something like the following so that Dagger would inject the dependencies itself, however doing so gives me an error.

@Provides
@Singleton
public Dispatcher providesDispatcher(Dispatcher dispacher) {
    return dispacher;
}

Perhaps there is another way to define singletons that would allow me to inject other singletons into them though?

Any help is appreciated.

EDIT: I just realized that I am doing the second approach with another Singleton, however it's a slightly different case as I'm mapping an implementation to an interface:

@Provides
@Singleton
public Tracker providesTracker(TrackerImpl tracker) {
    return tracker;
}

TrackerImpl is injected with an instance of the PPreferences mentioned above as well.

When I try to have it create the Dispatcher with the second example this is the error I get:

error: Unknown error java.lang.IllegalStateException thrown by javac in graph validation: Dependency cycle:
0. com.example.test.Dispatcher bound by @Singleton/ProviderMethodBinding[provideKey="com.example.test.Dispatcher", memberskey="null"]
0. com.example.test.Dispatcher
spierce7
  • 14,797
  • 13
  • 65
  • 106
  • Why do you need such construction? Just to avoid writing real singleton code? – Eugen Martynov Jan 20 '14 at 16:36
  • I don't have a problem with writing singleton code, but since I'm using dependency injection, it makes sense to adopt it across the board for the entire app. It seems it was even simpler than I thought if you take a look at stenrs answer. – spierce7 Jan 26 '14 at 05:28

1 Answers1

9

You do not need to have a @Provides method (on the module) for creating a Dispatcher singleton instance. Just annotate the Dispatcher constructor with @Inject and the class with @Singleton. Dagger will use that instance whenever you inject a Dispatcher instance.

@Singleton
public class Dispatcher 
{
    @Inject
    public Dispatcher(..)
}
Sten Roger Sandvik
  • 2,526
  • 2
  • 19
  • 16
  • I didn't realize Dagger let me declare Singletons so conveniently. I don't suppose there is any way around me adding every single class that injects Dispatcher to the @Module classes array is there? – spierce7 Jan 26 '14 at 05:27
  • 1
    @spierce7 no, to fully utilze the compile time verification, it is required to fill all injects in – thatsIch Mar 23 '14 at 10:47
  • Which I've come to find is both a blessing and a curse. – spierce7 Mar 23 '14 at 22:44
  • I have a similar question - but the way described here by @Sten Roger Sandvik does not seem to work? I am using dagger 2 and posted a question here http://stackoverflow.com/q/31417795/1041533 - would be great if someone could check it out and point me in the right direction. – AgentKnopf Jul 15 '15 at 11:43