使用GWT和Gin的交叉活动引用

使用GWT和Gin的交叉活动引用,gwt,dependency-injection,mvp,guice,gwt-gin,Gwt,Dependency Injection,Mvp,Guice,Gwt Gin,我有一个使用活动和地点的GWT MVP应用程序。这是受到毛罗·贝尔塔佩勒(Mauro Bertapelle)的样本(in)的启发,显然是基于他的一些作品 问题是:我让LoginActivity进行RPC调用,对于成功登录,该调用将返回一个用户。此用户具有一个角色(例如,管理员、普通用户、来宾)。一些视图和活动(包括NavigatorView)依赖于此角色来显示或执行它们所显示的内容。如何将此用户实例转移到其他活动 我没有客户工厂;注入(Gin)用于实例化提供我的活动/演示者的ActivityPr

我有一个使用活动和地点的GWT MVP应用程序。这是受到毛罗·贝尔塔佩勒(Mauro Bertapelle)的样本(in)的启发,显然是基于他的一些作品

问题是:我让LoginActivity进行RPC调用,对于成功登录,该调用将返回一个用户。此用户具有一个角色(例如,管理员、普通用户、来宾)。一些视图和活动(包括NavigatorView)依赖于此角色来显示或执行它们所显示的内容。如何将此用户实例转移到其他活动

我没有客户工厂;注入(Gin)用于实例化提供我的活动/演示者的ActivityProviders中的视图,ActivityProviders被注入到我的ActivityMapper中。因此,这可能会归结为一个问题:如何在需要的地方获取用户引用?这似乎类似于MVP中的关于全局引用

假设我是一个杜松子酒新手,这是我第一次尝试使用它。我猜有一种“杜松子酒法”可以实现这一点,但我对杜松子酒的了解还不足以知道最好的方法(如果应该使用杜松子酒的话)

非常感谢

编辑1:尽管我尽了最大努力搜索了一个类似的问题,但我还是发现了一个与我几乎相同的问题(查找“相关”链接的SO算法是否比搜索更好?)。我认为大卫的回答是正确的


我认为EventBus解决方案是不可能的。我遵循的是在每个地方更改时都要实例化活动,因此单凭一个事件本身是不够的。

我在最近的一个项目中也有类似的要求

当我从登录(或注销)RPC收到回复时,我会在EventBus上发送一个自定义AuthenticationEvent。所有对此感兴趣的活动都将收听此活动。AuthenticationEvent具有对AppUser对象的引用,如果用户刚刚注销,则该对象为null。AppUser包含所有必要的数据(特权、组等),以便活动可以对其进行检查和操作

关于全局引用:您可以有一个带有静态方法的类来提供您需要的数据。此类在内部保存对所需实例的单例引用。在我的示例中,我有静态方法AppUtils.getCurrentUser()。在内部,它保存对AppUser的引用,还侦听AuthenticationEvent以设置/重置此字段

作为旁注:不要依赖客户端来强制执行访问限制-您应该将您的RPC servlet分为两个组:public和private。公共RPC可以被任何人访问(这基本上是登录/注销RPC和一些其他公共信息RPC),而私有RPC要求对用户进行身份验证。可以根据路径/servlet设置访问限制:

更新:

  • 正如您所注意到的,在这个设置中,使用静态方法的类是不可取的,因为它是不可替换的,这会阻止测试(这是使用GIN的全部要点)

  • 解决方案是将一个包含globals(AppUtils)的实用程序类注入到需要globals的活动中。应用程序应该在GIN配置中声明为singleton,因为一个实例对于整个应用程序已经足够了

  • 如果要延迟依赖项的初始化(AppUtil是dependency),是否使用
    提供程序
    只是一个问题。由于AppUtils是整个应用程序的一个单例,因此将其初始化是没有意义的

  • 有时,您会遇到屏幕上显示多个活动的情况(在我的例子中是菜单栏和信息栏)。在这种情况下,当用户登录时,您将需要一种通知他们更改的方法。使用事件总线


  • 我在最近的一个项目中也有类似的要求

    当我从登录(或注销)RPC收到回复时,我会在EventBus上发送一个自定义AuthenticationEvent。所有对此感兴趣的活动都将收听此活动。AuthenticationEvent具有对AppUser对象的引用,如果用户刚刚注销,则该对象为null。AppUser包含所有必要的数据(特权、组等),以便活动可以对其进行检查和操作

    关于全局引用:您可以有一个带有静态方法的类来提供您需要的数据。此类在内部保存对所需实例的单例引用。在我的示例中,我有静态方法AppUtils.getCurrentUser()。在内部,它保存对AppUser的引用,还侦听AuthenticationEvent以设置/重置此字段

    作为旁注:不要依赖客户端来强制执行访问限制-您应该将您的RPC servlet分为两个组:public和private。公共RPC可以被任何人访问(这基本上是登录/注销RPC和一些其他公共信息RPC),而私有RPC要求对用户进行身份验证。可以根据路径/servlet设置访问限制:

    更新:

  • 正如您所注意到的,在这个设置中,使用静态方法的类是不可取的,因为它是不可替换的,这会阻止测试(这是使用GIN的全部要点)

  • 解决方案是将一个包含globals(AppUtils)的实用程序类注入到需要globals的活动中。应用程序应该在GIN配置中声明为singleton,因为一个实例对于整个应用程序已经足够了

  • 如果要延迟依赖项的初始化(AppUtil是dependency),是否使用
    提供程序
    只是一个问题。由于AppUtils是整个应用程序的一个单例,因此将其初始化是没有意义的

  • 有时,您会遇到屏幕上显示多个活动的情况(在我的例子中是菜单栏和信息栏)。在这种情况下,当用户登录时,您将需要一种通知他们更改的方法。使用事件总线


  • 我在服务器端使用Guice,在客户端也同样适用,就是绑定到自定义提供程序。不过,在您的情况下,您必须将提供程序设置为单例,并将值从
    @Singleton
    public class CurrentUserProvider implements Provider<User> {
      private User currentUser;
    
      public User get() { return currentUser; }
      public void setCurrentValue(User currentUser) {
        this.currentUser = currentUser;
      }
    }