3

通常、GWT プロジェクトには次のようなコード パターンがあります。

Menu errorMenu = new Menu(user, userController, -1);
Menu  searchMenu = new Menu(user, userController, 0);

errorView.setMenu(errorMenu);
searchView.setMenu(searchMenu);

Gin/Guice を使用して、およびその他の「ビュー」Menuにインスタンスを挿入するにはどうすればよいですか。ErrorView

public ErrorView implements View {
 // Inject menu instance here
 private Menu menu;
}

そのため、オブジェクトを手動で作成して設定する必要はありませんか?

また、Menuクラスについては、インスタンス化されるたびに各 Menu インスタンスに渡す必要がないように、「user」オブジェクトと「userController」オブジェクトをどのように挿入できますか。

4

1 に答える 1

10

このチュートリアルhttp://code.google.com/p/google-gin/wiki/GinTutorialの助けを借りて、問題はそれほど難しくないように見えます。ビューにメニュー インスタンスを挿入するには、いくつかの手順を実行する必要があります。

  1. メニュー フィールドに @Inject アノテーションを追加します。

    public ErrorView implements View {
    
      @Inject
      private Menu menu;
    }
    
    public SearchView implements View {
    
      @Inject
      private Menu menu;
    }
    

    ただし、この場合、View オブジェクトの初期化中 (コンストラクターで)、メニュー フィールドは null になります。したがって、このフィールドをコンストラクターのパラメーターに追加することをお勧めします。

    public ErrorView implements View {
    
      private final Menu menu;
    
      @Inject
      public ErrorView(Menu menu) {
        this.menu = menu;
      }
    }
    
    public SearchView implements View {
    
      private final Menu menu;
    
      @Inject
      public SearchView(Menu menu) {
        this.menu = menu;
      }
    }
    

    もちろん、ErrorView のコンストラクターに他の多くのパラメーターがある場合は機能しません。それらもすべて注入する必要があるためです。

  2. new Menu(user, userController, -1)ここで、ErrorView のメニュー フィールドを注入し、SearchView の別のメニュー フィールドを -に注入する必要があることを GIN が認識していることを確認する必要がありますnew Menu(user, userController, 0)。これにはいくつかの方法があります。

    • メニュー フィールドに注釈@Named("searchMenu")を追加します。@Named("errorMenu")

      public ErrorView implements View {
      
        @Inject
        @Named("errorMenu")
        private Menu menu;
      }
      

      また

      public ErrorView implements View {
      
        private final Menu menu;
      
        @Inject
        public ErrorView(@Named("errorMenu") Menu menu) {
          this.menu = menu;
        }
      } 
      

      GIN モジュールでは、この注釈の定義を提供する必要があります。

          public class ApplicationGinModule extends AbstractGinModule {
      
            protected void configure() {
              bind(Menu.class).annotatedWith(Names.named("errorMenu")).to(DefaultErrorMenu.class);
              bind(Menu.class).annotatedWith(Names.named("searchMenu")).to(DefaultSearchMenu.class);
      
              //assume that User and UserController classes have default constructors  
              //otherwise you should provide correct injection depending on your business-logic
              bind(User.class).in(Singleton.class); 
              bind(UserController.class).in(Singleton.class);  
            }
          }
      
          public class DefaultErrorMenu extends Menu {
      
            @Inject
            public DefaultErrorMenu(User user, UserController userController) {
              super(user, userController, -1);
            }
          }
      
          public class DefaultSearchMenu extends Menu {
      
            @Inject
            public DefaultSearchMenu(User user, UserController userController) {
              super(user, userController, 0);
            }
          }
      
    • 独自の注釈@SearchMenu@ErrorMenuメニュー フィールドを作成し、モジュールで定義します。

      注釈のサンプル:

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
      @BindingAnnotation
      public @interface ErrorMenu {
      }
      

      使用法:

      public ErrorView implements View {
      
        @Inject
        @ErrorMenu
        private Menu menu;
      }
      

      また

      public ErrorView implements View {
      
        private final Menu menu;
      
        @Inject
        public ErrorView(@ErrorMenu Menu menu) {
          this.menu = menu;
        }
      } 
      

      次に、 @Named("ErrorMenu") を定義したとおりにアノテーションを定義します。

      bind(Menu.class).annotatedWith(ErrorMenu.class).to(DefaultErrorMenu.class);
      

いくつかの例では、メニュー フィールドを final にしてセッターを削除していますが、メニューの変更可能な状態が本当に必要な場合は、そのままにしておくことができます。

于 2012-05-02T07:15:54.810 に答える