Search code examples
guiceguice-3

Binding a constructor argument based on the Annotation of the class


I have an interface: InterfaceA.

I have a class: ConcreteA.

I also have two annotations: @AnnotA and @AnnotB.

I have done the following bindings:

bind(InterfaceA).annotatedWith(AnnotA).to(ConcreteA);
bind(InterfaceA).annotatedWith(AnnotB).to(ConcreteA);

Next, class ConcreteA has a constructor that takes a String argument called hostName.

class ConcreteA
{
    @Inject
    public ConcreteA(@Named("hostName") hostName) {
    }

    ... <rest of class>
}

I need code to describe the following:

If ConcretaA is using @AnnotA then bind hostName with String value of 'localhost'

If ConcreteA is using @AnnotB then bind hostName with String value of 'externalhost'

Any ideas of a solution for this?


Solution

  • I think in your case, you might consider putting each binding in its own private module.

    class MyModule() { 
      install(new PrivateModule() {
        public void configure() {
           bind(InterfaceA).to(ConcreteA);
           bind(String.class).annotatedWith(Names.named("hostName").to("localhost");
           expose(InterfaceA).annotatedWith(AnnotA.class);
        }});
      install(new PrivateModule() {
        public void configure() {
           bind(InterfaceA).to(ConcreteB);
           bind(String.class).annotatedWith(Names.named("hostName").to("externalhost");
           expose(InterfaceA).annotatedWith(AnnotB.class);
        }});
    }
    

    (This is from memory and syntax may not be 100% correct.)

    For more detail, start with the Guice FAQ, and search that page for "robot legs" -- I'm not joking :)

    There is even more detail behind the two additional links from that section of the FAQ.