Your existing implementation is the best you can get.
Let's write out a general IPaymentFactory for clarity:
public interface IPaymentFactory {
IPayment create(/* ... */);
}
So instances of IPaymentFactory define one method, that takes in some number of parameters and returns an instance of IPayment. You could write an implementation yourself, and evidently you have, but Guice's FactoryModuleBuilder provides interface implementations like this one automatically. You never need to define anything else about that class: Guice will wire up the constructor for you, and bind it to IPaymentFactory so you can inject IPaymentFactory instances, call create(...)
with your parameters, and get IPayment instances.
It looks like what you're going for is a factory that takes an Enum:
public interface IPaymentFactory {
IPayment create(PaymentType paymentType);
}
...but given that CashPayment takes one arbitrary parameter, and CardPayment takes two arbitrary parameters, and given that the selection between them requires a mapping to an arbitrary PaymentType enum, you haven't given Guice nearly enough information to construct the right object.
Guice FactoryModuleBuilder is designed more for combining constructor parameters with dependencies:
// Constructor:
@Inject public BitcoinPayment(
@Assisted long value, // varies by instance as a constructor parameter
BitcoinService bitcoinService // passed-in dependency satisfied by Guice
) { /* ... */ }
// Factory interface:
public IBitcoinPaymentFactory {
BitcoinPayment create(long value); // users don't need to know about dependencies!
}
// Factory binding...
install(new FactoryModuleBuilder().build(IBitcoinPaymentFactory.class));
// ...which lets Guice write the equivalent of:
public GeneratedBitcoinPaymentFactory implements IBitcoinPaymentFactory {
@Inject Provider<BitcoinService> bitcoinServiceProvider;
@Override public BitcoinPayment create(long value) {
return new BitcoinPayment(value, bitcoinServiceProvider.get());
}
}
On one hand, the factory is dumber than you think: It just combines parameters with dependencies to get one whole list. On the other, it's handy: you specify the dependency list once, and Guice does the rest.
In summary: FactoryModuleBuilder won't solve your problem, but it COULD help you create factories for CashPayment and CardPayment, which you could then inject into your manual PaymentFactory implementation (which will still need to exist in some form or another).
P.S. In your example, which might be a "toy problem" for demonstration, you may not need to use Guice. Guice is a great solution for service objects that require dependencies, but data objects (like a payment) or other objects that don't seem to need dependencies (like GuiceService or NaiveService) can be constructed directly using constructors. Once they start needing Guice-injected dependencies, it should be pretty easy to make them Guice-aware.