Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice partial injection example

This example is taken from a book about Dependency Injection.

On page 87, there is this example.

public class NewsletterManager {
  private final List<Recipient> recipients;
  private final DelivererFactory factory; // The book notes this as injected

  public NewsletterManager(List<Recipient> rs, DelivererFactory factory) {
    this.recipients = rs;
    this.factory = factory;
  }

  public void send(Newsletter letter) {
    for (Recipient recipient : recipients) {
      Deliverer d = factory.forLetter(letter);
      d.deliverTo(recipient);
    }
  }

}

I understand what the code is meant to do, but what I don't understand is how to instanciate, or configure my Module, so that I can create instances of this class.

It seems that the DelivererFactory is injected. The examples does not say how, but let's admit it's through a constructor injection. In that case, how to pass the List<Recipient> instance which is particular to the NewsletterManager instance I want? How can I use Guice to instantiate my NewsletterManager with a module-configured DelivererFactory and a particular List<Recipient> instance ?

What I don't get is how there can be at the same time automatically injected objects and instance-specific objects in the signature of the constructor. In that case, I don't see how I can get an instance of NewsletterManager having only my List<Recipient>. Do I have to rely on a factory ? In that case, what is the use of the DelivererFactory injection, since I'll have to inject it in my factory too...

I hope my question is clear enough...

like image 869
glmxndr Avatar asked Jul 18 '12 16:07

glmxndr


1 Answers

You are right, this kind of injection can only be solved by using a factory.

If you have Foo(A a, B b) with A being injected and B passed at runtime, you will need a Factory FooFactory.createFoo(B b), that internally holds the reference to A.

Luckily, Guice has the concept of @Assisted Injection. You will have to provide the Interface of the factory, but can leave the "magic" of implementation to Guice.

Its pretty well documented: https://github.com/google/guice/wiki/AssistedInject

You will need an extra dependency to com.google.inject.extensions » guice-assisted-inject

like image 164
Jan Galinski Avatar answered Oct 19 '22 21:10

Jan Galinski