So far, I successfully used google guice 2. While migrating to guice 3.0, I had troubles with assisted inject factories. Assume the following code
public interface Currency {}
public class SwissFrancs implements Currency {}
public interface Payment<T extends Currency> {}
public class RealPayment implements Payment<SwissFrancs> {
@Inject
RealPayment(@Assisted Date date) {}
}
public interface PaymentFactory {
Payment<Currency> create(Date date);
}
public SwissFrancPaymentModule extends AbstractModule {
protected void configure() {
install(new FactoryModuleBuilder()
.implement(Payment.class, RealPayment.class)
.build(PaymentFactory.class));
}
}
While creating the injector, I get the following exception:
com.google.inject.CreationException: Guice creation errors:
1) Payment<Currency> is an interface, not a concrete class.
Unable to create AssistedInject factory. while locating Payment<Currency>
at PaymentFactory.create(PaymentFactory.java:1)
With the assisted inject creator from guice 2 my configuration works:
bind(PaymentFactory.class).toProvider(
FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));
The only workaround I found so far is to remove the generic parameter from the return type of the factory method:
public interface PaymentFactory {
Payment create(Date date);
}
Does anybody know, why guice 3 doesn’t like the generic parameter in the factory method or what I generally misunderstood about assisted inject factories? Thanks!
There are two issues with your code above.
First,
RealPaymentimplementsPayment<SwissFrancs>, butPaymentFactory.createreturnsPayment<Currency>. APayment<SwissFrancs>cannot be returned from a method that returnsPayment<Currency>. If you change the return type ofcreatetoPayment<? extends Currency>, thenRealPaymentwill work (because it’s aPaymentfor something that extendsCurrency).Second, you DO need to use the version of
implementthat takes aTypeLiteralas its first argument. The way to do that is to use an anonymous inner class. To represent `Payment’ you can useSee the Javadoc for that
TypeLiteralconstructor for more information.