One option would be to inject a Provider<InjectedObject>
into your class, as Jesse mentioned:
public class MyClass {
private final List<InjectedObject> injectedObjects;
@Inject
public MyClass(Provider<InjectedObject> injectedObjectProvider) {
List<InjectedObject> objects = new ArrayList<InjectedObject>();
for (int i = 0; i < 5; i++) {
objects.add(injectedObjectProvider.get());
}
injectedObjects = Collections.unmodifiableList(objects);
}
}
Doing this can be problematic. If InjectedObject
is scoped as @Singleton
or @RequestScoped
, then each time you call injectedObjectProvider.get()
you would get the same reference. Another problem with injecting a Provider
to do this is it wouldn't be clear from the API that MyClass
depends on multiple instances of InjectedObject. Finally, you've hardcoded in MyClass
that it needs to be injected with five instances.
It's rare that you will need to inject a Provider
into an object. Usually when I do this, it's because the scope of the current object means that it will be longer-lived than the scope of the dependent object (for instance, a @Singleton
that needs access to a @RequestScoped
object).
Instead of injecting a Provider
, you can inject a List<InjectedObject>
into the constructor, and create a provider method in a Guice module:
@Provides
MyClass prividesMyClass(Provider<InjectedObject> injectedObjectProvider) {
List<InjectedObject> objects = new ArrayList<InjectedObject>();
for (int i = 0; i < 5; i++) {
objects.add(injectedObjectProvider.get());
}
return new MyClass(objects);
}
(you could, of course, bind using a TypeLiteral
)
Why is this better? Even though you are still hard-coding five objects in this code, it isn't hard-coded in MyClass
, so clients of MyClass
(including the tests for MyClass
itself) can choose to construct the object in different ways.
If hard-coding this knowledge in a Guice module isn't a good idea, you can instead create an interface that has a more specific contract than Provider
public interface InjectedObjectRepository {
List<InjectedObject> getInjectedObjects();
}
Even if you decide that you want MyClass
to be responsible for knowing how many instances to create, you might want to create an interface (perhaps named InjectedObjectSupplier
so you could document explicitly that you expect a unique instance every time.