How to connect different interfaces using Google Guice?

Do I need to create a new module with an interface associated with another implementation?

Chef newChef = Guice.createInjector(Stage.DEVELOPMENT, new Module() { @Override public void configure(Binder binder) { binder.bind(FortuneService.class).to(FortuneServiceImpl.class); } }).getInstance(Chef.class); Chef newChef2 = Guice.createInjector(Stage.DEVELOPMENT, new Module() { @Override public void configure(Binder binder) { binder.bind(FortuneService.class).to(FortuneServiceImpl2.class); } }).getInstance(Chef.class); 

I can not touch the chef class and interfaces. I am just a client related to Chef FortuneService with different interfaces at runtime.

+4
source share
3 answers

Take a look at the Robot Legs section described in the Guice FAQ. "How to create a robot with two" Leg "objects, the left one, which is entered using LeftFoot, and the right one with the right panel." But there is only one Leg class that is reused in both contexts.

There is a PrivateModules solution there. It uses two separate private modules: @Left and @Right. Each of them has a binding to the unoccupied Foot.class and Leg.class and provides a binding for the annotated Leg.class:

 class LegModule extends PrivateModule { private final Class<? extends Annotation> annotation; LegModule(Class<? extends Annotation> annotation) { this.annotation = annotation; } @Override protected void configure() { bind(Leg.class).annotatedWith(annotation).to(Leg.class); expose(Leg.class).annotatedWith(annotation); bindFoot(); } abstract void bindFoot(); } 

... and glue it all together:

  public static void main(String[] args) { Injector injector = Guice.createInjector( new LegModule(Left.class) { @Override void bindFoot() { bind(Foot.class).toInstance(new Foot("leftie")); } }, new LegModule(Right.class) { @Override void bindFoot() { bind(Foot.class).toInstance(new Foot("righty")); } }); } 
+7
source

How do you decide which FortuneService implementation is required for the chef? You cannot bind the same interface to different implementations, preventing Guice from distinguishing between the two. You should use something like this.

 bind(FortuneService.class).annotatedWith(Names.named("1").to(FortuneServiceImpl.class); bind(FortuneService.class).annotatedWith(Names.named("2").to(FortuneServiceImpl2.class); 

For more information see here .

+3
source

I think you can use the @Provides annotation. See here .

0
source

Source: https://habr.com/ru/post/1309211/


All Articles