2012-02-06 20 views
12

Supongamos que tengo alguna clase Message como la siguiente. (Esta es una clase inventada por simplicidad.)Guice inyectando solamente parte del constructor

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

Ya que tengo diferentes MessageSender implementaciones, y puede ser que desee unidad de prueba de esta capacidad de enviar, creo que debería inyectará el MessageSender en Message 's send() método . ¿Pero cómo hago esto?

Todos los ejemplos Guice que he visto y que entiendo parece hacer la inyección en el 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); 
    } 
} 

Pero mi clase Message toma en un argumento text en su constructor, que no lo hago querer inyectar Entonces, ¿qué se supone que debo hacer?

(Nota:.. Yo soy un completo novato Google Guice Creo que comprendo la inyección de dependencias, pero no entiendo cómo realmente ponerlo en práctica con Guice)

Respuesta

19

Se podría utilizar la inyección para proporcionar el asistida texto a través de una fábrica, junto con el remitente del mensaje instancia por 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); 
    } 
} 

fábrica:

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

Módulo:

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

uso:

@Inject MessageFactory messageFactory; 

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

Assisted Injection Wiki

Cuestiones relacionadas