Let's say I'm developing an application which uses a service to do
something totally awesome.
public class MyAppModule extends PrivateModule {
bind(AwesomeService.class).to(AwesomeServiceImpl.class);
expose(AwesomeService.class);
}
Now the particular implementation of my AwesomeService needs a few things
to be as awesome as it is:
class AwesomeServiceImpl implements AwesomeService {
@Inject
AwesomeServiceImpl(BlueService blue, RedService red, ExecutorService
executor) { ... }
}
It just so happens that some upstanding internet denizen has created a
standalone jar with guice modules that provide both Red and Blue Services.
So I'll add the jar to my classpath and modify MyAppModule so that my
AwesomeService can use the third pary Red and Blue Services:
public class MyAppModule extends PrivateModule {
install(new RedModule());
install(new BlueModule());
bind(AwesomeService.class).to(AwesomeServiceImpl.class);
expose(AwesomeService.class);
}
I also need an ExecutorService for my AwesomeService, so I'll go ahead and
bind to an explicit instance for now:
public class MyAppModule extends PrivateModule {
install(new RedModule());
install(new BlueModule());
bind(ExecutorService.class).toInstance(Executors.newSingleThreadExecutor());
bind(AwesomeService.class).to(AwesomeServiceImpl.class);
expose(AwesomeService.class);
}
Ah, but damn, apparently my good internet friend decided to expose not only
the RedService and BlueService bindings that my AwesomeService needs, but
also an ExecutorService that I don't want:
public final class BlueModule extends PrivateModule {
bind(ExecutorService.class).toInstance(Executors.newCachedThreadPool());
bind(BlueService.class).to(BlueServiceImpl.class);
expose(ExecutorService.class);
expose(BlueService.class);
}
public final class RedModule extends PrivateModule {
bind(ExecutorService.class).toInstance(Executors.newCachedThreadPool());
bind(RedService.class).to(RedServiceImpl.class);
expose(ExecutorService.class);
expose(RedService.class);
}
No problem, I'll just wrap his modules in a private module and expose only
the services I care about:
public class MyAppModule extends PrivateModule {
install(new PrivateModule() {
install(new RedModule());
expose(RedService.class);
});
install(new PrivateModule() {
install(new BlueModule());
expose(BlueService.class);
});
bind(ExecutorService.class).toInstance(Executors.newSingleThreadExecutor());
bind(AwesomeService.class).to(AwesomeServiceImpl.class);
expose(AwesomeService.class);
}
Ahh, but damn again, my ExecutorService binding is inherited by my private
wrapper modules and is conflicting with the internal bindings defined in
the RedModule and BlueModule. I guess I could annotate or Name my
ExecutorService in my AwesomeService constructor, but what if I want that
ExecutorService to be a singleton shared all over my app, by 20, 30 or 40
different services. I'll have to pollute all my ExecutorService injections
with this annotation.
Or I suppose I could do some trickery, staggering the bindings and hiding
the ExecutorService so it doesn't conflict with the ExecutorService that
RedModule and BlueModule need, but this just seems wrong:
public class MyAppModule extends PrivateModule {
install(new PrivateModule() {
install(new RedModule());
expose(RedService.class);
});
install(new PrivateModule() {
install(new BlueModule());
expose(BlueService.class);
});
final Module myAppExecutorService = new PrivateModule() {
bind(ExecutorService.class).toInstance(Executors.newSingleThreadExecutor());
expose(ExecutorService.class);
};
install(new PrivateModule() {
install(myAppExecutorService);
bind(AwesomeService.class).to(AwesomeServiceImpl.class);
expose(AwesomeService.class);
});
expose(AwesomeService.class);
}
This seems like a common problem one would have using guice. Am I missing
something here? What is the best practice for this use case?
Any assistance would be greatly appreciated!
Minor Notes:
- the configure method declaration was elided in all modules shown
- BlueModule and RedModule are intentionally marked final, so extending and
overriding the expose method is not a viable solution to the problem
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.