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.


Reply via email to