Domanda

Stiamo valutando l'utilizzo del progetto GIN in OUT GWT e hanno avuto buoni risultati con iniezione tipica tramite argomenti di costruttore.La cosa che abbiamo avuto difficoltà con è l'iniezione del livello del campo.I campi finiscono sempre per essere nullo.Qualcuno ha un buon esempio di come raggiungere correttamente l'iniezione del livello archiviato con Gin?

Aggiornamento:

Ecco un codice di esempio simile al nostro:

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

}
.

Nel codice sopra, ho rimosso la maggior parte del codice che non coinvolge Gin.Il testPresenter che il dettaglio del dettaglio richiede viene iniettato con successo, ma la handlermanager che il testpresenter richiede è sempre nullo.Come puoi vedere, la handlermanager iniettata non è utilizzata nel costruttore.

È stato utile?

Soluzione

Aggiornamento, guardando il codice di esempio:

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

Perché lo stai creando da solo, presuppone che tu abbia affrontato tutte le iniezioni. Rimuovi questo metodo e invocherà il costruttore predefinito (iniettando lì se necessario), visitare qualsiasi altro sito di iniezione.

Un altro problema che potresti essere in esecuzione: ci sono diversi implementazione di handlermanager, assicurati che tutti i tuoi riferimenti a Handlermanager utilizzino lo stesso pacchetto.


.

Risposta originale:

Sarà nulla quando il costruttore è in esecuzione, ma questo ha senso - come potrebbero essere qualsiasi altro valore, quando l'iniettore non ha avuto la possibilità di assegnare ancora tutti i campi. Considera come sarebbe riuscito a correre (espresso qui come Java discutibilmente legale, poiché i campi potrebbero non essere pubblici):

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

Nel momento in cui il campo è anche idoneo da assegnare, il tuo costruttore è già stato eseguito.

Se il campo è null quando viene eseguito un altro metodo, assicurarsi che il metodo non venga eseguito dal costruttore , ma dopo l'iniezione ha terminato il suo lavoro. Altri casi in cui potrebbe ancora essere nullo sarebbe @Inject Setter annotated.

Supponendo che non sia nessuno di questi casi (il modo più semplice per controllare è impostando un punto di interruzione e assicurandosi che l'iniettore non sia nello stack di chiamata), assicurarsi che il campo abbia un @Inject e che sia T Legato a un istanza Null.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top