Assisted injection stripped down

Assistedinject is cool. But there are chances that we don’t want so many interfaces when our code is simple and not likely to change. Here is a version do the same thing as assistedinject while without any interfaces and binding configuration:

Payment.java

public class Payment {
    CreditService creditService;
    AuthService authService;
    Date date;
    Money amount;
    
    @Inject
    public Payment(CreditService creditService, AuthService authService,
            Date startDate, Money amount) {
        this.creditService = creditService;
        this.authService = authService;
        this.date = startDate;
        this.amount = amount;
 
    }
}
 

PaymentFactory.java

public class PaymentFactory {
    CreditService creditService;
    AuthService authService;
    
    @Inject
    public PaymentFactory(CreditService creditService, AuthService authService){
        this.authService = authService;
        this.creditService = creditService;
    }
    
    public Payment get(Date date, Money amount){
        return new Payment(this.creditService,this.authService,date,amount);
    }
}

PaymentClient

    public static void main(String[] args){
        Injector injector = Guice.createInjector();
        PaymentFactory paymentFactory = injector.getInstance(PaymentFactory.class);
        Payment payment = paymentFactory.get(new Date(), new Money());
        payment.doSomeThing();
    }

 

I use to think that the “new” is the enemy of Guice, and should be totally eleminated. Truely, the “new” breaks the chain of Guice object graph, but can we create a ‘perfect’ world without “new”? No. The Guice is perfect in creating object graph upfront, but it can’t predict the dependencies in the runtime. In fact, altimately, the “new” is still the only option in such situation. Then, how could we get out of the delima? It is actually simple: let Guice do what it is good for, and so to “new”.

Digg This

Advertisements

Provide object with dependency

Guice provide “Provider” interface to support the refactoring of the existing factory methods, like this:

     public class GumProducer implements Provider<Gum>{
         @Override
         public Gum get() {
             return new Gum();
         }
     }

But sometime the Gum is not that simple, what if it has its own dependencies, like GumPack? GumProducer is nothing special to Guice except the get() method, so just treat it as a common class and leave the dependencies to Guice:

     public class GumProducer implements Provider<Gum>{
         private GumPack pack;
         @Inject
         public GumProducer(GumPack pack){
             this.pack = pack;
         }
      
         @Override
         public Gum get() {
            return new Gum(this.pack);
         }
     }