2

古斯用户!我在这里遇到了一种情况,我可以找到解决方法,但我对我的解决方案不满意。它与Using the provider from two different scopes非常相似,但那里的答案不适合我的情况。

我有一个这样的课程,我在很多地方都注入了它:

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!");
            }
        }
    }
}

提供者采用试错法来查找可用的会话(Web 会话或作业会话),并返回用户获得的第一个会话。它之所以起作用,是@com.google.inject.Inject(optional=true)因为范围是相互排斥的。

有没有更好的方法来实现这一目标?我只想为透明使用它的任何范围MyBusinessClass注入@AuthenticatedUser User,并让 Guice 模块/提供者找到正确的位置来获得令人满意的实例。

4

0 回答 0