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.
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));Thanks
public interface IPayment {
void pay();
}
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");
}
}
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+"]");
}
}
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);
}
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));
}
}
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();
}
}