Package com.google.inject.assistedinject
Class FactoryModuleBuilder
- java.lang.Object
-
- com.google.inject.assistedinject.FactoryModuleBuilder
-
public final class FactoryModuleBuilder extends Object
Provides a factory that combines the caller's arguments with injector-supplied values to construct objects.Defining a factory
Create an interface whose methods return the constructed type, or any of its supertypes. The method's parameters are the arguments required to build the constructed type.public interface PaymentFactory { Payment create(Date startDate, Money amount); }
You can name your factory methods whatever you like, such as create, createPayment or newPayment.Creating a type that accepts factory parameters
constructedType
is a concrete class with an @Inject
-annotated constructor. In addition to injector-supplied parameters, the constructor should have parameters that match each of the factory method's parameters. Each factory-supplied parameter requires an @Assisted
annotation. This serves to document that the parameter is not bound by your application's modules.public class RealPayment implements Payment { @Inject public RealPayment( CreditService creditService, AuthService authService, @Assisted Date startDate, @Assisted Money amount) { ... } }
Multiple factory methods for the same type
If the factory contains many methods that return the same type, you can create multiple constructors in your concrete class, each constructor marked with with @AssistedInject
, in order to match the different parameters types of the factory methods.public interface PaymentFactory { Payment create(Date startDate, Money amount); Payment createWithoutDate(Money amount); } public class RealPayment implements Payment { @AssistedInject public RealPayment( CreditService creditService, AuthService authService, @Assisted Date startDate, @Assisted Money amount) { ... } @AssistedInject public RealPayment( CreditService creditService, AuthService authService, @Assisted Money amount) { ... } }
Configuring simple factories
In yourmodule
, install aFactoryModuleBuilder
that creates the factory:install(new FactoryModuleBuilder() .implement(Payment.class, RealPayment.class) .build(PaymentFactory.class));
As a side-effect of this binding, Guice will inject the factory to initialize it for use. The factory cannot be used until the injector has been initialized.Configuring complex factories
Factories can create an arbitrary number of objects, one per each method. Each factory method can be configured using.implement
.public interface OrderFactory { Payment create(Date startDate, Money amount); Shipment create(Customer customer, Item item); Receipt create(Payment payment, Shipment shipment); } [...] install(new FactoryModuleBuilder() .implement(Payment.class, RealPayment.class) // excluding .implement for Shipment means the implementation class // will be 'Shipment' itself, which is legal if it's not an interface. .implement(Receipt.class, RealReceipt.class) .build(OrderFactory.class));
Using the factory
Inject your factory into your application classes. When you use the factory, your arguments will be combined with values from the injector to construct an instance.public class PaymentAction { @Inject private PaymentFactory paymentFactory; public void doPayment(Money amount) { Payment payment = paymentFactory.create(new Date(), amount); payment.apply(); } }
Making parameter types distinct
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:public interface PaymentFactory { Payment create( @Assisted("startDate") Date startDate, @Assisted("dueDate") Date dueDate, Money amount); }
...and to the concrete type's constructor parameters:public class RealPayment implements Payment { @Inject public RealPayment( CreditService creditService, AuthService authService, @Assisted("startDate") Date startDate, @Assisted("dueDate") Date dueDate, @Assisted Money amount) { ... } }
Values are created by Guice
Returned factories use child injectors to create values. The values are eligible for method interception. In addition, @Inject members will be injected before they are returned.More configuration options
In addition to simply specifying an implementation class for any returned type, factories' return values can be automatic or can be configured to use annotations:If you just want to return the types specified in the factory, do not configure any implementations:
public interface FruitFactory { Apple getApple(Color color); } ... protected void configure() { install(new FactoryModuleBuilder().build(FruitFactory.class)); }
Note that any type returned by the factory in this manner needs to be an implementation class.To return two different implementations for the same interface from your factory, use binding annotations on your return types:
interface CarFactory { @Named("fast") Car getFastCar(Color color); @Named("clean") Car getCleanCar(Color color); } ... protected void configure() { install(new FactoryModuleBuilder() .implement(Car.class, Names.named("fast"), Porsche.class) .implement(Car.class, Names.named("clean"), Prius.class) .build(CarFactory.class)); }
Implementation limitations
As a limitation of the implementation, it is prohibited to declare a factory method that accepts aProvider
as one of its arguments.- Since:
- 3.0
-
-
Constructor Summary
Constructors Constructor Description FactoryModuleBuilder()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description <F> Module
build(Key<F> factoryInterface)
<F> Module
build(TypeLiteral<F> factoryInterface)
See the factory configuration examples atFactoryModuleBuilder
.<F> Module
build(Class<F> factoryInterface)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Key<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Key<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, Annotation annotation, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, Annotation annotation, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, Class<? extends Annotation> annotationType, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(TypeLiteral<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, Annotation annotation, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, Annotation annotation, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, Class<? extends Annotation> annotationType, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
implement(Class<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.<T> FactoryModuleBuilder
withLookups(MethodHandles.Lookup lookups)
Typically called viawithLookups(MethodHandles.lookup())
.
-
-
-
Method Detail
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, Annotation annotation, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, Annotation annotation, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Annotation annotation, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Annotation annotation, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, Class<? extends Annotation> annotationType, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Class<T> source, Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Class<? extends Annotation> annotationType, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(TypeLiteral<T> source, Class<? extends Annotation> annotationType, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Key<T> source, Class<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
implement
public <T> FactoryModuleBuilder implement(Key<T> source, TypeLiteral<? extends T> target)
See the factory configuration examples atFactoryModuleBuilder
.
-
withLookups
public <T> FactoryModuleBuilder withLookups(MethodHandles.Lookup lookups)
Typically called viawithLookups(MethodHandles.lookup())
. Sets the MethodHandles.Lookup that the factory implementation will use to call default methods on the factory interface. While this is not always required, it is always OK to set it. It is required if the factory passed tobuild(java.lang.Class<F>)
is non-public and javac generated default methods while compiling it (which javac can sometimes do if the factory uses generic types).Guice will try to work properly even if this method is not called (or called with a lookups that doesn't have access to the factory), but doing so requires reflection into the JDK, which may break at any time (and trigger unsafe access warnings).
- Since:
- 5.0
-
build
public <F> Module build(Class<F> factoryInterface)
See the factory configuration examples atFactoryModuleBuilder
.
-
build
public <F> Module build(TypeLiteral<F> factoryInterface)
See the factory configuration examples atFactoryModuleBuilder
.
-
-