There are several points to mention. But don't worry we will get you
where you want to be.
1. Guice modules do not get injected. Modules define what is binded
in the injector. This means the modules are used to construct the
injector. So they exist before the injector does. This makes it
impossible for them to have anything injected into them.
PlayFramework does its own magic. It creates the injector for you.
To do this you can pass it a list of module classes in the
PlayFramework application.conf. If you read the documentation of
PlayFramework [1] it states that it optionally will pass the Play
Configuration to the constructor of the module. This is done by
PlayFramework and has nothing to do with Guice. Note that there is
not @Inject annotation on the constructor of the module.
2. Getting instances of module A into module B. This may sound
logical in the beginning but it is not how Guice works. If the
injector is constructed from multiple modules then it knows the
union of the binding defined in all modules. This is also the reason
why you cannot bind the same class twice. The injector simply
wouldn't know which binding to use. So a single module may not know
all bindings but the injector which is created in the end will.
3. Passing the DAO service to the Mail class. As you mention it in a
comment this is the actual goal and this is the core competence of
Guice. Your only misconception was that you try to do this in the
binding. You need to do this in the Mail class. I recommend using
constructor injection:
@Singleton
public class Mail {
private final DAO dao;
@Inject
public Mail(DAO dao) {
this.dao = dao;
}
}
That's it. Technically you don't even need to bind the Mail class in
your module. Guice will simply create a just in time binding. Never
the less I would recommend creating an interface for the mail
service and then specify which class implements the interface. This
is especially useful for testing since you can replace the actual
implementation with a mock or a stub for testing services depending
on the mail service.
public class EmailModule extends AbstractModule {
@Override
protected void configure() {
bind(Mail.class).to(MailImpl.class);
}
}
Hope this gets you started and if you encounter more questions
report back.
[1]
https://www.playframework.com/documentation/2.5.x/JavaDependencyInjection#Providing-custom-bindings