2012-02-06 4 views
12

Supponiamo di avere una classe Message simile alla seguente. (Questa è una classe inventata per semplicità.)Guice inserisce solo alcune delle funzioni di costruzione

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); 
    } 
} 

Dal momento che ho diverse MessageSender implementazioni, e potrebbe desiderare di test di unità questa capacità di invio, penso che dovrei essere l'iniezione del send() metodo MessageSender in Message s' . Ma come faccio a fare questo?

Tutti gli esempi Guice che ho visto e che ho capito sembra fare l'iniezione nel costruttore:

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); 
    } 
} 

Ma la mia classe Message prende in un argomento text nel suo costruttore, che non mi voglio iniettare. Quindi cosa dovrei fare invece?

(Nota:.. Io sono un completo niubbo Google Guice Credo di capire la dipendenza iniezione, ma non capisco come implementare in realtà con Guice)

risposta

19

si potrebbe usare assistito ad iniezione per fornire il testo attraverso una fabbrica, insieme al mittente del messaggio un'istanza per 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); 
    } 
} 

fabbrica:

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

Modulo:

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

utilizzo:

@Inject MessageFactory messageFactory; 

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

Assisted Injection Wiki