正如 Jesse 提到的,一种选择是将 aProvider<InjectedObject>
注入您的班级:
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);
}
}
这样做可能会有问题。如果InjectedObject
作用域为@Singleton
or @RequestScoped
,那么每次调用injectedObjectProvider.get()
时都会得到相同的引用。注入 a 来执行此操作的另一个问题是,从依赖于多个 InjectedObject 实例Provider
的 API 中不清楚。MyClass
最后,您已经硬编码,MyClass
因为它需要注入五个实例。
您很少需要将 aProvider
注入对象。通常当我这样做时,这是因为当前对象的范围意味着它将比依赖对象的范围更长寿(例如,@Singleton
需要访问@RequestScoped
对象的 a )。
Provider
您可以将 aList<InjectedObject>
注入构造函数,并在 Guice 模块中创建提供程序方法,而不是注入 a :
@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);
}
(当然,您可以使用 a 绑定TypeLiteral
)
为什么这样更好?尽管您仍然在此代码中硬编码五个对象,但它并没有硬编码在 中MyClass
,因此MyClass
(包括MyClass
自身的测试)的客户端可以选择以不同的方式构造对象。
如果在 Guice 模块中硬编码这些知识不是一个好主意,您可以改为创建一个具有比Provider
public interface InjectedObjectRepository {
List<InjectedObject> getInjectedObjects();
}
即使您决定要MyClass
负责知道要创建多少个实例,您也可能希望创建一个接口(也许命名InjectedObjectSupplier
以便您可以明确记录您每次都期望一个唯一的实例。