質問

GINをGWTに使用して評価し、コンストラクターの引数を介した典型的な注入で良好な結果が得られています。私たちが難しかったことは現場レベルの注射です。フィールドは常にNULLになり終わっています。誰もがGINで提出されたレベル注射を適切に達成する方法の良い例を持っていますか?

更新:

これは私たちのものと同様のコード例です。

public class MVP implements EntryPoint {

  public static final HandlerManager EVENT_BUS = new HandlerManager(null);
  private final MVPInjector _injector = GWT.create(MVPInjector.class);

  public void onModuleLoad() {
    // set up layout for module
    RootLayoutPanel.get().add(mainPanel);

    // initialize presenters
    ListPresenter listPresenter = _injector.listPresenter();
    DetailPresenter detailPresenter = _injector.detailPresenter();

    listPresenter.go(listContainer);
    detailPresenter.go(detailContainer);

    // simulate data coming in from RPC call
    EVENT_BUS.fireEvent(new DataReadyEvent(getData()));
  }
}

public class ListPresenter {

  private final HandlerManager _eventBus;
  private final Map<String, Fruit> _myRecords = new HashMap<String, Fruit>();
  private final Display _view;

  @Inject
  public ListPresenter(Display argView, HandlerManager argEventBus) {
    _eventBus = argEventBus;
    _view = argView;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());
  }

  public interface Display {
    public Widget asWidget();

    public void clear();

    public SingleSelectionModel<ViewProxy> getSelectionModel();

    public void setData(List<ViewProxy> argData);
  }
}

public class DetailPresenter {

  private final HandlerManager _eventBus;
  private final Display _view;
  private Fruit _myRecord;

  @Inject
  private ImagePresenterFactory _imagePresenterFactory;

  @Inject
  private TestPresenter _testPresenter;

  @Inject
  public DetailPresenter(Display argView, HandlerManager argEventBus) {
    _view = argView;
    _eventBus = argEventBus;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());

    if (_testPresenter != null) {
      _testPresenter.go();
    }
  }

  public interface Display {
    public Widget asWidget();

    public HasText getDescriptionControl();

    public HasClickHandlers getImageControl();

    public HasText getNameControl();

    public HasClickHandlers getSaveControl();

    public void setEnabledControls(boolean argEnabled);
  }
}

public class TestPresenter {

  @Inject
  HandlerManager _eventBus;

  public TestPresenter() {}

  public void go() {
    if (_eventBus != null) {
      _eventBus.toString();
    }
    else {
      // event bus was not injected
    }
  }
}

@GinModules(MVPModule.class)
public interface MVPInjector extends Ginjector {

  DetailPresenter detailPresenter();

  ListPresenter listPresenter();

}

public class MVPModule extends AbstractGinModule {

  @Provides
  @Singleton
  public HandlerManager getEventBus() {
    return MVP.EVENT_BUS;
  }

  @Provides
  public TestPresenter getTestPresenter() {
    return new TestPresenter();
  }

  @Override
  protected void configure() {
    bind(ListPresenter.Display.class).to(ListView.class);
    bind(DetailPresenter.Display.class).to(DetailView.class);
    bind(ImagePresenter.Display.class).to(ImagePopup.class);
    install(new GinFactoryModuleBuilder().build(ImagePresenterFactory.class));
  }

  public interface ImagePresenterFactory {
    public ImagePresenter createImagePresenter(ImageResource argImage);
  }

}
.

上記のコードでは、Ginを含まないコードのほとんどを削除しました。TestPresenterが必要なTestPresenterは正常に注入されますが、TestPresenterが必要とするHandLermanagerは常にNULLです。ご覧のとおり、注入されたHandLermanagerはコンストラクタでは使用されません。

役に立ちましたか?

解決

更新、サンプルコードを見る:

@Provides
public TestPresenter getTestPresenter() {
  return new TestPresenter();
}
.

あなたはそれを自分で作成しているので、それはあなたがどんな注射に扱ったと仮定します。このメソッドを削除し、デフォルトのコンストラクタ(必要ならばそこに注入する)を呼び出してから、他の噴射サイトを訪問します。

他の1つの問題に遭遇することができる:いくつかのHandLermanager Implesがあり、HandLermanagerへの参照すべてが同じパッケージを使用していることを確認してください。


オリジナルアンサー:

コンストラクタが実行されているときはNULLになりますが、インジェクタがすべてのフィールドをまだ割り当てる機会がない場合は、必須です。これがどのように実行される可能性があるかを検討します(フィールドが公開されていない可能性があるように、正常に法的なJavaとして表現されています):

InstanceToInject instance = new InstanceToInject(...);
instance.field = provideFieldValue();
.

フィールドが割り当てられている資格がある場合、コンストラクタはすでに実行されています。

別のメソッドが実行されたときにフィールドがnullの場合は、コンストラクタによってメソッドがでないことを確認してくださいが、注入後の作業が終了した後です。それがまだヌルであるかもしれない他のケースは、@Inject注釈付きセッターになるでしょう。

それがそれらの場合でもないと仮定すると(最も簡単な方法はブレークポイントを設定し、インジェクタがコールスタックにないことを確認することであること)、フィールドに@Injectがあることを確認しています。 t NULLインスタンスにバインドします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top