1

This is a slightly different question from the other answered questions about constructor parameter (or at least that's what I think so, course I may be wrong). So am using a MapBinder to store a bunch of implementations and then pick one during runtime based of some criteria. Here is some code:

public interface MessageService {
  void send();
}

public class FacebookMessageService implements MessageService {
  private final String name;

  @Inject
  public FacebookMessageService(String name) {
    this.name = name;
  }

  public void send() {
    System.out.println("Sending message via facebook service to " + name);
  }
}

public class MessageModule extends AbstractModule {
  @Override
  protected void configure() {
    MapBinder<String, MessageService> mapBinder = MapBinder.newMapBinder<.....>
    mapBinder.addBinding("facebook").to(FacebookMessageService.class);
  }
}

public class MessageClient {
  @Inject
  Map<String, MessageService> map; //Mapbinder being injected

  public void callSender() {
    Injector injector = Guice.createInjector(new MessageModule());
    injector.injectMembers(this);

    MessageService service = map.get("facebook");
    service.send();
  }
}

I am unable to figure out how to get the FacebookMessageService with the name parameter? If I use AssistedInject with a Factory then I am not able to figure out how to inject the implementation into the MapBinder.

noMAD
  • 7,744
  • 19
  • 56
  • 94
  • I haven't used MapBinder, but according to [this](http://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/multibindings/MapBinder.html), you're supposed to inject the MapBinder itself, not the key, is that what you want? – Alper Akture Jun 18 '15 at 19:04
  • @AlperAkture Am not sure what you mean by `key` here but the mapBinder is being injected in the client. The above code works but I don't know how to inject the `name` parameter so it basically prints "Sending message via facebook service to" without a `name` – noMAD Jun 18 '15 at 19:13
  • Can you load the FacebookMessageService constructor arg from a prop file, like [this](http://stackoverflow.com/a/28332904/1138137)? – Alper Akture Jun 18 '15 at 19:18
  • That makes sense for config but in my case its an interface. Sorry I have a String up there but that's just for simplifying the question. :) I didn't know about that config though. Thanks! :) – noMAD Jun 18 '15 at 20:22
  • np, maybe I didn't get your use case exactly. What did you want injected into the FacebookMessageService constructor? – Alper Akture Jun 18 '15 at 20:46
  • Could you maybe not inject the name param, and do: `mapbinder.addBinding("facebook").toInstance(new FacebookMessageService("some string value"));` – Alper Akture Jun 18 '15 at 21:09

1 Answers1

0

You can inject the 'name' parameter.

public class FacebookMessageService implements MessageService {
    private final String name;

    @Inject
    public FacebookMessageService(@Named("facebookServiceName") String name) {
       this.name = name;
    }
}

public class MessageModule extends AbstractModule {
    @Override
    protected void configure() {
        // bind the "facebookServiceName"
        // I think this binding should exist before the map binding
        bindConstant().annotatedWith(Names.named("facebookServiceName"))
                      .to("insert your argument here");

        MapBinder<String, MessageService> mapBinder = MapBinder.newMapBinder<.....>
        mapBinder.addBinding("facebook").to(FacebookMessageService.class);
    }
}

Put a debug point in the FacebookMessageService constructor to see whether this works.