Это невозможно сделать с Guice идиоматически, и это не является его основным фокусом.
jfpoilpret сказал все, что можно сказать, ноЯ хотел бы подойти к проблеме с другой стороны, где у вас есть возможность (возможно) решить вашу проблему, потеряв безопасность типов.
Итак, в вашем коде вы просите Guice получить экземпляр вашегоRunner<T, V>
класс, подобный этому
injector.getInstance(Runner.class);
, но это не может быть решено Guice, потому что Runner<T, V>
имеет зависимость от GenericDAO<T, V>
, но вы не связали точную реализацию для него.Итак, как сказал jfpoilpret, вы должны связать некоторые конкретные реализации для него в вашем модуле.
Я предполагаю, что вы хотите определить точную реализацию GenericDAO<T, V>
, которую вы передаетеваш Runner<T, V>
основан на некоторых входных данных, тип данных которых неизвестен во время компиляции.Теперь давайте предположим, что у вас есть две реализации.
bind(new TypeLiteral<GenericDAO<String, ObjectID>>(){}).to(StringDAO.class);
bind(new TypeLiteral<GenericDAO<Double, ObjectID>>(){}).to(IntegerDAO.class);
На основе различных типов входов вы можете сделать это
Injector injector = Guice.createInjector(new RunnerModule());
// possible input which you get from *somewhere* dynamically
Object object = 1.0;
TypeLiteral<?> matchedTypeLiteral = null;
for (Key<?> key : injector.getAllBindings().keySet()) {
TypeLiteral<?> typeLiteral = key.getTypeLiteral();
Type type = typeLiteral.getType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType() == GenericDAO.class) {
List<Type> actualTypeArguments = Arrays.asList(parameterizedType.getActualTypeArguments());
if (actualTypeArguments.get(0) == object.getClass())
matchedTypeLiteral = typeLiteral;
}
}
};
Runner<?, ?> runner = new Runner<>((GenericDAO<?, ?>) injector.getInstance(Key.get(matchedTypeLiteral)));
System.out.println(runner.dao.getClass()); // IntegerDAO.class
Если Object object = "string";
, то other реализация будет найдена.Это, конечно, довольно уродливо и может быть улучшено проверкой подклассов и прочего, но я думаю, вы поняли идею.Суть в том, что вы не можете обойти это.
Если вам удастся это сделать ( обойти это ), пожалуйста, напишите мне по электронной почте, потому что я хотел бы узнать об этом!Я столкнулся с той же проблемой, с которой вы столкнулись не так давно.Я написал простой кодек BSON , в котором я хотел загрузить конкретные реализации универсального интерфейса, основанные на типе произвольного ввода.Это хорошо работало с отображениями Java-to-BSON, но я не мог сделать это каким-либо другим способом, поэтому я выбрал более простое решение.