Одним из вариантов было бы придать Provider<InjectedObject>
в своем классе, как уже упоминалось Jesse:
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
или @RequestScoped
, то каждый раз, когда вы звоните injectedObjectProvider.get()
, вы получите ту же ссылку. Другая проблема с инъекцией Provider
для этого заключается в том, что из API не будет ясно, что MyClass
зависит от нескольких экземпляров InjectedObject. Наконец, вы указали в MyClass
, что необходимо ввести пять экземпляров.
Очень редко вам нужно ввести Provider
в объект. Обычно, когда я это делаю, это потому, что область действия текущего объекта означает, что он будет более долговечным, чем область зависимого объекта (например, @Singleton
, которому нужен доступ к объекту @RequestScoped
).
Вместо введения в Provider
, вы можете впрыснуть List<InjectedObject>
в конструктор и создать метод поставщика в модуле Guice:
@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);
}
(можно, конечно, связать с использованием TypeLiteral
)
Почему это лучше? Несмотря на то что вы все еще жестко кодируете пять объектов в этом коде, он не жестко закодирован в MyClass
, поэтому клиенты MyClass
(включая тесты для самого MyClass
) могут выбирать объект по-разному.
Если жесткое кодирование эти знания в модуле Guice не является хорошей идеей, вы можете вместо этого создать интерфейс, который имеет более конкретный контракт, чем Provider
public interface InjectedObjectRepository {
List<InjectedObject> getInjectedObjects();
}
Даже если вы решите, что вы хотите MyClass
чтобы быть ответственным за знание количества экземпляров для создания, вы можете создать интерфейс (возможно, с именем InjectedObjectSupplier
, чтобы вы могли явно указывать, что каждый раз вы ожидаете уникального экземпляра.
Спасибо за предложение - причины, имеющие несколько при условии, жадность, чтобы иметь возможность разместить их в ThreadPool - количество экземпляров в пуле будет зависеть от количества доступных ядер. – Rich
Как бы вы это сделали, если у вас не было контроля над исходным кодом MyClass, но просто хотелось вставить его с помощью привязок и другого кода в конфигурацию модуля (желательно, не используя Multibindings, поскольку это еще не совместимо с Gin)? – Snekse
Snekse, вы можете создать метод @Provides, который принимает Поставщик как параметр и вызывает конструктор MyClass в конце. –