Hi Marshall,
Thanks for the reply, and I wholeheartedly agree with you, BlueModule's
author lacked foresight.
I did consider using Modules.override, but I actually don't want to change
BlueModule's ExecutorService binding, you see BlueService actually uses
BlueModule's ExecutorService, and if I replace it with my application's
ExecutorService, BlueService will start kicking off threads in my
application's executor service and neither I nor BlueService want that.
class BlueServiceImpl {
@Inject
BlueServiceImpl(ExecutorService executor) { ... }
}
Thanks,
Matt
On Friday, April 26, 2013 12:17:44 PM UTC-7, Marshall Pierce wrote:
>
> Looks like you could just use Modules.override [1]:
>
> install(Modules.override(new BlueModule()).with(new
> MyExecutorServiceModule()));
>
> [1]
> http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/util/Modules.html#override(com.google.inject.Module...)
>
>
>
> Though, it would have been nice if BlueModule's author hadn't so rudely
> bound ExecutorService, since that makes it hard on users of his library.
> When releasing code externally I apply annotations to bindings of common
> classes from the JDK or other libraries so that users don't get these
> unpleasant surprises.
>
> -Marshall
>
> On Apr 26, 2013, at 11:54 AM, Matthew Madson
> <[email protected]<javascript:>>
> wrote:
>
> > 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] <javascript:>.
> > To post to this group, send email to
> > [email protected]<javascript:>.
>
> > Visit this group at http://groups.google.com/group/google-guice?hl=en.
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> >
>
>
--
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.