I'd like to complement Marcin's response, by adding that you don't have to limit yourself to using toInstance()
or provider methods in such a situation.
The following will work just as well:
bind(Person.class).annotatedWith(Driver.class).to(MartyMcFly.class).in(Singleton.class);
bind(Person.class).annotatedWith(Inventor.class).to(DocBrown.class).in(Singleton.class);
[...]
@Inject
public BackToTheFuture(@Driver Person marty, @Inventor Person doc) { ... }
Guice will inject the dependencies as usual when instantiating the MartyMcFly and DocBrown classes.
Note that it also works when you want to bind multiple singletons of the same type:
bind(Person.class).annotatedWith(Driver.class).to(Person.class).in(Singleton.class);
bind(Person.class).annotatedWith(Inventor.class).to(Person.class).in(Singleton.class);
For this to work, you must make sure that Person
is not bound in the Singleton scope, either explicitely in the Guice module, or with the @Singleton
annotation. More details in this Gist.
Edit:
The sample code I give as an example comes from a Guice Grapher Test.
Looking at the Guice tests is a great way to better understand how to use the API (which also applies to every project with good unit tests).