Guice - how to implement a factory that returns different implementations

3,802 views
Skip to first unread message

rails

unread,
Aug 9, 2014, 6:29:50 PM8/9/14
to google...@googlegroups.com

Lets say I have a service called Guice service and here is its constructor

public GuiceService(IPayment payment) {
    this.payment = payment;
}

And my code used to create it using an Enum

IPayment payment = new PaymentFactory.create(PaymentType.Cash);
NaiveService naiveService = new NaiveService(payment);

And I had to have a factory implementation somewhere. Something like this

public IPayment create(PaymentType paymentType) {
    IPayment cardPayment = null;
    switch (paymentType) {
        case Cash:
            cardPayment = new CashPayment(100);
            break;
        case Card:
            cardPayment = new CardPayment(10, 100);
            break;
    }
    return cardPayment;

Now I want to use Guice and I guess I want to use FactoryModuleBuilder.

  1. What is the way to do it if I have more that one implentation of IPayment.
    (e.g. CardPayment, CashPayment)
    This works for one

    install(new FactoryModuleBuilder()
       .implement(IPayment.class, CashPayment.class)
       .build(IPaymentFactory.class));
  2. How do I implement the constructor ?
    will it still get IPayment? or will it get the factoryImpl created by Guice?

Thanks

Michael

unread,
Aug 13, 2014, 10:17:18 PM8/13/14
to google...@googlegroups.com
Hi,

You don't need an implementation of Payment Factory by yourself, just define the factory interface and method, Guice will do the injection.

something like this :

public interface IPayment {

void pay();

}


The implementations of IPayment:


public class CashPayment implements IPayment{

       private int cash;

       @Inject

       public CashPayment(@Assisted int cash) {

               this.cash = cash;

       }

       @Override


        public void pay() {


                System.out.println("Pay["+cash+"] from Cash");


        }


}


another one :








public class CardPayment implements IPayment{




        private int cash;


       


        private int card;


       


        @Inject


        public CardPayment(@Assisted("cash") int cash, @Assisted("card") int card) {


                this.card = card;


                this.cash = cash;


        }




        @Override


        public void pay() {


                System.out.println("Pay["+cash+"] from Card["+card+"]");


        }


}


Then define your factory:









public interface PaymentFactory {


        @Named("cash") IPayment getCashPayment(int cash);


       


        /*


         * The types of the factory method's parameters must be distinct.


         * To use multiple parameters of the same type, use a named @Assisted annotation to disambiguate the parameters.


         * The names must be applied to the factory method's parameters


         */


        @Named("card") IPayment getCardPayment(@Assisted("cash") int cash, @Assisted("card") int card);


}


your config module :









public class PaymentModule extends AbstractModule {




        @Override


        protected void configure() {


                install(new FactoryModuleBuilder()


                                .implement(IPayment.class, Names.named("cash"),CashPayment.class)


                                .implement(IPayment.class, Names.named("card"),CardPayment.class)


                                .build(PaymentFactory.class));


        }




}


Let's take a test :








public class RealPayment {




        public static void main(String[] args) {


                Injector injector = Guice.createInjector(new PaymentModule());


                PaymentFactory factory = injector.getInstance(PaymentFactory.class);


                factory.getCashPayment(10).pay();


                factory.getCardPayment(10, 123456789).pay();


        }




}


For more usage of factory injection , please refer to :


https://github.com/google/guice/wiki/AssistedInject

在 2014年8月10日星期日UTC+8上午6时29分50秒,rails写道:
Reply all
Reply to author
Forward
0 new messages