Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在GWT活动中使用GIN_Gwt_Dependency Injection_Gwt Gin_Gwt Activities - Fatal编程技术网

在GWT活动中使用GIN

在GWT活动中使用GIN,gwt,dependency-injection,gwt-gin,gwt-activities,Gwt,Dependency Injection,Gwt Gin,Gwt Activities,我的每个活动都需要一个相应的单例视图实现。将它们注入活动的最佳策略是什么 构造函数注入从ActivityMapper的getActivity()调用活动构造函数。ctor已经有一个参数(一个放置对象)。我必须创建包含所有可能视图的ActivityMapper。不好 方法注入-“这样注释的函数在构造函数执行后自动执行。”(GWT在运行中,第2版。)“在执行了ctor之后”显然不够快,因为在活动的start()时视图(或以这种方式注入的RPC服务)仍然没有初始化方法被调用,我得到一个NPE 在活动的

我的每个活动都需要一个相应的单例视图实现。将它们注入活动的最佳策略是什么

  • 构造函数注入从ActivityMapper的getActivity()调用活动构造函数。ctor已经有一个参数(一个放置对象)。我必须创建包含所有可能视图的ActivityMapper。不好

  • 方法注入-“这样注释的函数在构造函数执行后自动执行。”(GWT在运行中,第2版。)“在执行了ctor之后”显然不够快,因为在活动的
    start()时视图(或以这种方式注入的RPC服务)仍然没有初始化
    方法被调用,我得到一个NPE

  • 在活动的ctor中使用GWT.create构建注入器。没用,因为他们不再是单身汉了


  • 对我们最有效的方法是使用辅助注射

    根据具体情况,我们在活动本身、包(用于构建该包中的所有活动)或ActivityMapper中定义了活动工厂。

    顺便说一句,要使方法注入工作,您仍然必须通过GIN创建活动,因此您将遇到与构造函数注入相同的问题。没有魔法,GIN不会神奇地注入它不知道、甚至不知道何时实例化的类。您可以通过向Ginjector添加方法来显式触发方法注入,但我不建议这样做(您的代码将依赖于Ginjector,如果可以的话,这是您应该避免的):


    最后一句话:我不会将place对象直接传递给活动。尝试分离位置和活动,这允许您通过更改“外壳”布局和活动映射器来移动东西(例如,构建移动或平板电脑版本,在主视图和详细视图之间切换,而不是并排显示)。要真正解耦它们,您必须构建某种导航器,它将抽象您的
    placeController.goTo()
    调用,以便您的活动永远不会处理位置。

    根据我的经验,一个好的做法是使用单独的活动映射器来处理位置和活动(映射)。在您拥有演示者的活动中,以下是一个活动示例:

    public class ActivityOne extends AbstractActivity {
    
      @Inject
      private Presenter presenter;
    
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        presenter.go(panel);
      }
    
    }
    
    演示者将视图注入其中,在调用“go”方法时构造视图(演示者)。演示者在
    GIN
    模块中声明为singleton,视图通常是singleton(有些例外,比如出现在许多地方的小部件)

    想法是将联系人与视图移动到演示者内部(因为演示者的目标是根据
    MVP
    ,处理逻辑并从视图检索/更新数据)。 在演示者内部,您还将拥有
    RPC
    服务,您不必声明它们,因为
    GIN
    将通过调用
    GWT.create“神奇地”为您创建实例
    下面是一个简单演示者的示例:

        public class PresenterOneImpl implements Presenter {
    
          @Inject
          private MyView view;
    
    
          @Inject
          private SomeRpcServiceAsync someRpc;
    
    
          @Override
          public void go(AcceptsOneWidget panel) {
            view.setPresenter(this);
            panel.setWidget(view);
            updateTheViewWithData();
          }
    }
    

    最后,我必须指出,有一些活动,比如菜单,直接处理位置和视图,以显示当前状态。这些活动缓存在映射器中,以避免每次更改位置时都出现新实例。

    我选择了一种稍微不同的方法,该方法具有您所需的所有灵活性。我不记得是从哪里学来这种设计模式的,但这不是我的主意。我创建这样的活动

    public class MyActivity extends AbstractActivity{
    
        private MyView view;
        @Inject static PlaceController pc;
    
    
        @Inject
        public MyActivity(MyView view) {
            super();
            this.view = view;
        }
    
        public MyActivity withPlace(MyPlace myPlace) {
            return this;
        }
    ...
    }
    
    然后我在活动映射器中使用它,如下所示:

    public class MyMapper implements ActivityMapper {
    
        @Inject Provider<MyActivity> myActivityProvider;
    
        public Activity getActivity(Place place) {
    
            if ( place instanceof MyPlace){
                return myActivityProvider.get().withPlace(place);
            } else if
    ...
    
    公共类MyMapper实现ActivityMapper{
    @注入提供者myActivityProvider;
    公共活动getActivity(地点){
    如果(我的位置的位置实例){
    返回myActivityProvider.get().withPlace(place);
    }否则如果
    ...
    

    还要确保视图在gin模块文件中声明为singleton。

    Hi Thomas,这正是我们在应用程序(使用factory)中所做的,并且工作良好。但是,您建议如何将其与gin的AsyncProvider集成以进行代码拆分?(我们使用的是ActivityAsyncProxy)
    public class MyActivity extends AbstractActivity{
    
        private MyView view;
        @Inject static PlaceController pc;
    
    
        @Inject
        public MyActivity(MyView view) {
            super();
            this.view = view;
        }
    
        public MyActivity withPlace(MyPlace myPlace) {
            return this;
        }
    ...
    }
    
    public class MyMapper implements ActivityMapper {
    
        @Inject Provider<MyActivity> myActivityProvider;
    
        public Activity getActivity(Place place) {
    
            if ( place instanceof MyPlace){
                return myActivityProvider.get().withPlace(place);
            } else if
    ...