Guice injecting only some of the constructor

空扰寡人 提交于 2019-11-30 13:17:17

问题


Suppose I have some Message class like the following. (This is a made-up class for simplicity.)

public class Message {
  private String text;

  public Message(String text) {
    this.text = text;
  }

  public void send(Person recipient) {
    // I think I should be Guice-injecting the sender.
    MessageSender sender = new EmailBasedMessageSender();
    sender.send(recipient, this.text);
  }
}

Since I have different MessageSender implementations, and might want to unit test this sending ability, I think I should be injecting the MessageSender in Message's send() method. But how do I do this?

All the Guice examples I've seen and that I understand seem to do the injection in the constructor:

public class Message {
  private String text;
  private MessageSender sender;

  // ??? I don't know what to do here, since the `text` argument shouldn't be injected.
  @Inject
  public Message(String text, MessageSender sender) {
    this.text = text;
    this.sender = sender;
  }

  public void send(Person recipient) {
    this.sender.send(recipient, this.text);
  }
}

public class MessageSenderModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(MessageSender.class).to(EmailBasedMessageSender.class);
  }
}

But my Message class takes in a text argument in its constructor, which I don't want to inject. So what am I supposed to do instead?

(Note: I'm a complete Google Guice noob. I think I understand dependency injection, but I don't understand how to actually implement it with Guice.)


回答1:


You could use assisted injection to provide the text through a factory, along with the message sender instantiated by Guice:

public class Message {
  private String text;
  private MessageSender sender;

  @Inject
  public Message(@Assisted String text, MessageSender sender) {
    this.text = text;
    this.sender = sender;
  }

  public void send(Person recipient) {
    this.sender.send(recipient, this.text);
  }
}

Factory:

public interface MessageFactory{
    Message buildMessage(String text);
}

Module:

public class MessageSenderModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(MessageSender.class).to(EmailBasedMessageSender.class);
    FactoryModuleBuilder factoryModuleBuilder = new FactoryModuleBuilder();
    install(factoryModuleBuilder.build(MessageFactory.class));
  }
}

usage:

@Inject MessageFactory messageFactory;

void test(Recipient recipient){
  Message message = messageFactory.buildMessage("hey there");
  message.send(recipient);
}

Assisted Injection Wiki



来源:https://stackoverflow.com/questions/9154410/guice-injecting-only-some-of-the-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!