Guice - Как обеспечить один и тот же ключ по-разному в разных областях?
Guice пользователи! У меня есть ситуация здесь, и я мог бы найти обходной путь, но я не удовлетворен своим решением. Это очень похоже на использование провайдера из двух разных областей, но ответ там не подходит для моей ситуации.
У меня есть такой класс, который я внедряю во многих местах:
MyBusinessClass {
@Inject
MyBusinessClass(@AuthenticatedUser User user) {};
}
До какого-то момента в прошлом я только что получил @AuthenticatedUser User
из веб-сессии, поэтому у меня было:
bind(User.class).annotatedWith(AuthenticatedUser.class).toProvider(new AuthenticatedUserProvider());
...
public static class AuthenticatedUserProvider implements Provider<User> {
@Inject
Provider<Session> session;
public User get() {
return SessionUtil.getUserFromSession(session.get());
}
}
Эта проблема:
Это работало отлично, пока я не должен был использовать тот же MyBusinessClass
внутри другой области видимости Guice (а также вне области запроса). Я создал JobScope, очень похожий на пример области видимости в документации Guice, создал вид JobSession, связал его с JobScope и поместил @AuthenticatedUser User
экземпляр, который я хочу ввести, когда MyBusinessClass
используется внутри JobSession.
Вот где я не горжусь тем, что я сделал. Я "улучшил" своего провайдера, чтобы попытаться обеспечить @AuthenticatedUser User
для всех областей, и я закончил с этим уродливым провайдером:
public static class AuthenticatedUserProvider implements Provider<User> {
@com.google.inject.Inject(optional=true)
Provider<Session> session;
@com.google.inject.Inject(optional=true)
Provider<JobSession> jobSession;
@Override
public User get() {
try {
return SessionUtil.getUserFromSession(session.get());
} catch (Exception e) {
try {
return SessionUtil.getUserFromJobSession(jobSession.get());
} catch (Exception ee) {
throw new IllegalStateException("Current scope doesn't have a auth user!");
}
}
}
}
Поставщик использует метод проб и ошибок, чтобы определить, какой сеанс (веб-сеанс или сеанс задания) доступен, и вернуть пользователю первый, который он может получить. Это работает из-за @com.google.inject.Inject(optional=true)
а также потому, что области являются взаимоисключающими.
Есть ли лучший способ добиться этого? Я просто хочу иметь MyBusinessClass
вводится с @AuthenticatedUser User
для любой области он используется прозрачно, и пусть модули / провайдеры Guice находят подходящее место для получения удовлетворительного экземпляра.